6

Objective-C のソースと Objective-C++ のソースをコンパイルするときに違いがあります。

test.h での Class1 と Class2 の宣言:

#import <Foundation/Foundation.h>

@interface Class1 {
}
@end

@interface Class2 {
}
@end

さて、これは test.m での Objective-C の実装です:

#import "test.h"

@implementation Class1
/* static member */
static int mystatic;
@end


@implementation Class2
/* static member */
static int mystatic;
@end

私はこのコマンドで正常にコンパイルします:

gcc -arch armv6 -isysroot /Developer/.../iPhoneOS5.0.sdk -x objective-c -c test.m

今、私はこの目的の C++ 実装 test.mm (まったく同じソース) を正確に使用します。

#import "test.h"

@implementation Class1
/* static member */
static int mystatic;
@end


@implementation Class2
/* static member */
static int mystatic;
@end

そして、このコマンドラインでコンパイルします (-x オプションの違い):

gcc -arch armv6 -isysroot /Developer/.../iPhoneOS5.0.sdk -x objective-c++ -c test.mm

しかし、私はエラーが発生します:

test.mm:11 error: redefinition if 'int mystatic'

ObjC ではなく ObjC++ でこのエラーが発生するのはなぜですか?

4

1 に答える 1

6

これは、C と C++ の違いに要約されます。C では、同じ名前と同じ型の静的変数を再定義しても問題ありません。C++ では、同じことを行うとエラーになります。

C標準から:

ファイル スコープを持ち、初期化子がなく、ストレージ クラス指定子がないか、またはストレージ クラス指定子が static のオブジェクトの識別子の宣言は、暫定的な定義を構成します。翻訳単位に識別子の 1 つ以上の暫定的な定義が含まれており、翻訳単位にその識別子の外部定義が含まれていない場合、動作は、翻訳単位にその識別子のファイル スコープ宣言が含まれているかのように、複合型は次のようになります。 0 に等しい初期化子を使用して、翻訳単位の末尾を指定します。

C++ 標準から:

C.1.2、3.1 変更: C++ には、C のような「暫定的な定義」がありません。たとえば、ファイル スコープでは、

int i ;
int i ;

C では有効ですが、C++ では無効です。

Objective C に関する限り、この言語はクラス レベルでスコープが設定された変数をサポートしていません。static int mystatic;ブロック内で宣言@implementationすると、ブロック外で宣言した場合とまったく同じ効果があり@implementationます。クラス スコープの変数をエミュレートするには、クラス メソッド内で関数スコープの静的変数を使用します。

于 2012-07-05T14:19:53.760 に答える