4

重複の可能性:
名前のない名前空間が使用される理由とその利点は何ですか?

誰かのコードを見て、これは彼らが宣言したものです:

namespace {

  struct myStruct {
     int x;
     int y;
  } obj1;

}

..関数では、次のように使用されていることがわかります。

myStruct& var = obj1;

(通知namespaceは匿名です。)

私がそれがどのように使われているのかを見ると、なぜそれがこのように宣言され使われているのか理解できません。

このように宣言すると、何が違うのでしょうか。

また、ここに示す従来のスタイルではなく、このようにポインターが作成されるのはなぜですか。つまり、myStruct * ptr;

ありがとう!

4

4 に答える 4

11

匿名の名前空間内で宣言されたものはすべて、一意の認識できない名前を取得するため、他の翻訳単位から参照することはできません。したがって、匿名の名前空間は、現在の翻訳単位に対してのみローカルであることが保証され、別の翻訳単位と競合することはありません。

たとえば、 と言っnamespace { int i; }た場合、現在の翻訳単位のみがグローバル を参照することが保証されますi。この宣言が複数の異なる TU に含まれるヘッダーにある場合でも、各 TU はグローバル変数の独自のコピーを受け取ります (それぞれが異なる、認識できない完全修飾名を持ちます)。

staticこの効果は、C++03 でグローバル オブジェクトを宣言する (グローバル オブジェクトに内部リンケージを与える) のと似ていました。この場合、匿名名前空間内のオブジェクトは依然として外部リンケージを持つ可能性があります。C++11 では、名前のない名前空間の名前は 3.5/4 に従って内部リンケージを持つため、変数と関数に対する効果はそれらを宣言するのとまったく同じですstaticが、内部リンケージは変数と関数だけではありません (例: enum、クラス、テンプレート)、C++11 の時点では、常に名前のない名前空間を優先する必要があります。

于 2012-09-21T23:02:56.920 に答える
3

C++ では、指定された名前付きスコープに 1 つの定義しか持てません。複数の翻訳単位がある場合でも、定義は 1 つしか許可されませんが、コンパイラはすべての定義が実際に同一であることを保証しません。つまり、astructや a などのローカル型が必要な場合は、classその定義が他の翻訳単位のどこかにある別の型と競合しないようにする必要があります。ローカルで型を保護する方法がない限り、大規模なプロジェクトでこれを行うことはほとんど不可能です。これが、名前のない名前空間が提供するものです。名前のない名前空間内で定義された名前は、実行可能ファイル全体で一意です。

于 2012-09-21T23:04:08.110 に答える
2

基本的にキーワードと同じことを行いますstaticが、実際には内部リンケージを強制しません。変数はまだ外部にリンクされています。他の翻訳単位でその名前を解決する方法がありません。これは、テンプレート引数に外部リンケージが必要であるか、少なくとも外部リンケージを必要とするために使用されていたため、必要でした。

varもポインタではなく、参照です。ポインターではないため、他のポインターのように作成されません。

于 2012-09-21T23:05:11.567 に答える
0

Also, why is the pointer created like this rather than the traditional style shown here. i.e. myStruct *ptr;

It's a reference, not a pointer, that is created with myStruct& var = obj1; The same rationale applies to pointers, however. A lot of C++ programmers prefer myStruct* ptr over myStruct *ptr, myStruct& ref over myStruct &ref. The compiler doesn't care which you use. This style preference is for the reader of the code.

The reason for putting the asterisk or ampersand with the type rather than the variable is because that asterisk or ampersand is logically a part of the type. The type of ptr is pointer to myStruct. A potential problem arises with this scheme: Type* ptr1, ptr2; Because of rules inherited from C, ptr2 isn't a pointer. It's just an int.

There's an easy solution to this problem. Don't do that! In general, it is better to declare one variable per declaration, with an exception for simple things like int i,j,k; Don't mix pointers and non-pointers.

于 2012-09-22T01:47:31.113 に答える