56

foo私はそう宣言された整数を含む名前空間を持っていますbar...

foo.h:

namespace foo {
    int bar;
}

ここで、1 つのファイルにのみ含めるfoo.hと、これは問題なく機能します。foo.hしかし、 2 つ以上のファイルからインクルードすると問題が発生します。リンカ エラーが発生します。barとして宣言すると、複数のファイルstaticに含めることができることがわかりました。foo.h名前空間内で静的変数を宣言できることを知らなかったので、これは奇妙に思えます。(それは一体何の意味ですか?)

なぜこれが機能するのですか?さらに重要なのは、なぜそれがないと機能しない staticのですか? staticで使われるとはどういう意味ですかnamespace?

4

4 に答える 4

55

staticには、さまざまな文脈で複数の意味があります。この特定のコンテキストでは、変数に内部リンケージがあるため、そのヘッダーを含む各翻訳単位には、変数の独自のコピーがあることを意味します。

foo::barこれにより、リンカー エラーがサイレントになりますが、生成されたオブジェクト ファイルごとに個別の変数が維持されることに注意してください(変更は、異なるオブジェクト ファイル間では表示されません)。

単一の変数が必要な場合はextern、ヘッダーのように宣言し、1 つの翻訳単位で単一の定義を提供する必要があります。

于 2012-07-24T02:56:45.433 に答える
37

変数を として宣言するstaticと、そのスコープは指定された翻訳単位のみに限定されます。staticスコープがなければグローバルです。

static変数を.h ファイル内 (内外namespace; は関係ありません)として宣言し、そのヘッダー ファイルをさまざまな .cpp ファイルに含めると、static変数は各ファイルにローカルにスコープされ.cppます。
したがって、そのヘッダーを含むすべての .cpp ファイルには、その変数の独自のコピーが含まれます。

キーワードがないとstatic、コンパイラはその変数のコピーを 1 つだけ生成するため、ヘッダー ファイルを複数の .cpp ファイルに含めるとすぐに、リンカーは複数の定義について文句を言います。

于 2012-07-24T02:55:55.857 に答える
7

この問題は、変数の定義が複数あるために発生します。複数の非インライン関数定義が機能しないのと同じように、異なる翻訳単位の定義は互いに競合します。

変数を静的にすると、変数に内部リンケージが与えられるため、各翻訳単位には独自の独立したコピーがあります。

おそらく実際に必要なのは、(extern を使用して) 宣言のみをヘッダーに配置し、定義を実装ファイルに配置することです。

于 2012-07-24T02:59:11.477 に答える