2012-07-24 14 views
26

名前空間の非静的変数対静的、...そう宣言は、私は、名前空間の整数<code>bar</code>が含まれている<code>foo</code>を持って

がfoo.h:今、私は一つだけでfoo.hを含む場合

namespace foo { 
    int bar; 
} 

ファイル、これは正常に動作します。しかし、2つ以上のファイルからfoo.hを含めると問題が発生します。リンカーエラーが発生します。 barstaticと宣言すると、foo.hを複数のファイルに含めることができます。名前空間の中に静的変数を宣言することができないことに気づいていなかったので、これは私にとっては奇妙なことです。 (それはどういう意味ですか?)

これはなぜ機能しますか?さらに重要なのは、なぜでないのですかstaticなし? namespaceで使用される場合、staticの意味は何ですか?

+0

Upvote。正確に私の問題だったとそれを解決した:) –

答えて

26

異なるコンテキストでstaticに複数の意味があります。この特定の状況では、変数に内部リンケージがあることを意味します。したがって、ヘッダーを含む各翻訳単位には変数のコピーがあります。

これはリンカーのエラーを通知しませんが、生成されたオブジェクトファイルごとに別々のfoo::bar変数を保持しています(変更は異なるオブジェクトファイルには表示されません)。

1つの変数を使用する場合は、ヘッダーにexternと宣言し、1つの翻訳単位で1つの定義を指定する必要があります。

19

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

あなたは.hファイル内staticとして変数を宣言(内またはnamespaceなし;関係ありません)、および様々な.CPPファイルにそのヘッダーファイルをインクルード、static変数は、ローカル.cppのそれぞれにスコープとなりファイル。
これで、そのヘッダーを含むすべての.cppファイルには、その変数の独自のコピーが作成されます。

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

3

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

変数を静的にすると、変数に内部リンケージが設定されるため、各翻訳単位にはそれぞれ独自のコピーがあります。

おそらく実際には、宣言だけをヘッダに入れ(externを使用して)、その定義を実装ファイルに入れます。

関連する問題