308

新しい C++ ソフトウェア プロジェクトに参加したばかりで、その設計を理解しようとしています。プロジェクトは、名前のない名前空間を頻繁に使用します。たとえば、クラス定義ファイルで次のようなことが発生する場合があります。

// newusertype.cc
namespace {
  const int SIZE_OF_ARRAY_X;
  const int SIZE_OF_ARRAY_Y;
  bool getState(userType*,otherUserType*);
}

newusertype::newusertype(...) {...

名前のない名前空間を使用する原因となる設計上の考慮事項は何ですか? 長所と短所は何ですか?

4

6 に答える 6

241

名前のない名前空間は、識別子の変換単位をローカルにするためのユーティリティです。名前空間の翻訳単位ごとに一意の名前を選択するかのように動作します。

namespace unique { /* empty */ }
using namespace unique;
namespace unique { /* namespace body. stuff in here */ }

空の本体を使用する追加の手順は重要です。その::nameため、using ディレクティブが既に実行されているため、名前空間本体内で、その名前空間で定義されているような識別子を参照できます。

これは、複数の翻訳単位に存在できる無料の関数を呼び出すことがhelpでき、リンク時に衝突しないことを意味します。static効果は、識別子の宣言に入れることができる C で使用されるキーワードを使用するのとほとんど同じです。名前のない名前空間は優れた代替手段であり、型変換単位をローカルにすることさえできます。

namespace { int a1; }
static int a2;

両方aの は翻訳単位ローカルであり、リンク時に衝突しません。しかし、違いはa1、匿名名前空間の が一意の名前を取得することです。

comeau-computing のすばらしい記事を読んでください( Archive.org ミラー)。

于 2008-12-10T20:19:20.320 に答える
108

匿名の名前空間に何かがあるということは、それがこの翻訳単位(.cpp ファイルとそのすべてのインクルード) に対してローカルであることを意味します。これは、同じ名前の別のシンボルが他の場所で定義されている場合、 One Definition Rule (ODR)に違反しないことを意味します。

これは、静的グローバル変数または静的関数を持つ C の方法と同じですが、クラス定義にも使用できます ( staticC++ ではなく使用する必要があります)。

同じファイル内のすべての匿名名前空間は同じ名前空間として扱われ、異なるファイル内のすべての匿名名前空間は区別されます。匿名の名前空間は、次のものと同等です。

namespace __unique_compiler_generated_identifer0x42 {
    ...
}
using namespace __unique_compiler_generated_identifer0x42;
于 2008-12-10T20:08:44.537 に答える
24

名前のない名前空間は、クラス、変数、関数、およびオブジェクトへのアクセスを、それが定義されているファイルに制限します。static名前のない名前空間の機能は、C/C++ のキーワードに似ています。
staticキーワードは、グローバル変数と関数のアクセスを、それらが定義されているファイルに制限します。
名前のない名前空間とキーワードには違いがありますstatic。これは、名前のない名前空間が静的よりも優れているためです。staticキーワードは、変数、関数、およびオブジェクトで使用できますが、ユーザー定義クラスでは使用できません。
例えば:

static int x;  // Correct 

しかし、

static class xyz {/*Body of class*/} //Wrong
static structure {/*Body of structure*/} //Wrong

ただし、名前のない名前空間でも同じことが可能です。例えば、

 namespace {
           class xyz {/*Body of class*/}
           static structure {/*Body of structure*/}
  } //Correct
于 2016-05-26T16:56:48.297 に答える
13

この例は、参加したプロジェクトの人々が匿名の名前空間を理解していないことを示しています:)

namespace {
    const int SIZE_OF_ARRAY_X;
    const int SIZE_OF_ARRAY_Y;

constオブジェクトにはすでに静的なリンクがあり、別の翻訳単位の同じ名前の識別子と競合する可能性がないため、これらは匿名の名前空間にある必要はありません。

    bool getState(userType*,otherUserType*);
}

そして、これは実際には悲観的なものですgetState()。外部とのつながりがあります。シンボルテーブルを汚染しないため、通常は静的リンケージを選択することをお勧めします。書く方がいい

static bool getState(/*...*/);

ここ。私は同じ罠に陥りました(ファイル静的は匿名の名前空間を支持して非推奨になることを示唆する標準の文言があります)が、KDEのような大規模なC ++プロジェクトで作業すると、頭を正しい方向に向ける多くの人々がいます再び周り:)

于 2009-07-24T17:20:04.520 に答える
12

匿名の名前空間は、囲まれた変数、関数、クラスなどをそのファイル内でのみ使用できるようにします。あなたの例では、グローバル変数を回避する方法です。実行時またはコンパイル時のパフォーマンスの違いはありません。

「この変数、関数、クラスなどをpublicにするかprivateにするか」以外にメリットもデメリットもあまりありません。

于 2008-12-10T20:10:03.707 に答える