はこれを理解するには、compiling and linkingをよく理解している必要があります、とdeclarations and definitionsとの違い。
は、次のクラスを考えてみましょう:
ここ
//In header file
class Example {
static bool exampleStaticMember;
};
、exampleStaticMember
が宣言されていますが定義されていません。これは、exampleStaticMember
がアドレスを持っていなければならないという意味で使用されている場合には、別の定義が必要であることを意味します。一般に、クラス定義内の静的データメンバーの宣言は、そのメンバーの定義です。
通常、必要な宣言は、クラスのメンバーのその他の定義を含むcppファイルに入れられます。クラス定義と同じ名前空間になければなりません。定義は、一般的に次のようになります。
//In source file:
//This may optionally have an initialiser (eg "= true")
bool Example::exampleStaticMember;
定義は、任意のcppのファイルに入れることができるが、それはOne Definition Ruleを破る可能性が高いだろうので、それは、クラスとヘッダーに入れてはいけません。特別な場合として
静的メンバ変数は、CONST一体または列挙型である場合、それは、クラス定義の初期化子有することができる:この場合
//In header file
class Example {
static const int initialised = 15;
};
を、CPPファイルの定義でありますまだ必要ですが、初期化子を持つことはできません。
//In source file
//Note: no initialiser!
const int Example::initialised;
このように初期化された静的メンバーは、定数式で使用できます。テンプレートの静的データメンバーのために
テンプレート
、物事は少し異なっています。静的メンバは、クラスの残りの部分と一緒にヘッダで定義する必要があります。
//In header file
template<typename T>
class Example {
static int exampleInt;
static T exampleT;
}
template<typename T> int Example<T>::exampleInt;
template<typename T> T Example<T>::exampleT;
クラステンプレートの静的データメンバのための一つの定義ルールに特定の例外があるので、これは動作します。static
キーワードは、それは非常に異なる意味を取ることができるクラススコープにない機能やオブジェクトに適用される静的
の
その他の用途。
関数スコープ内のオブジェクトに適用すると、関数の最初の実行で初期化され、その後関数呼び出しの間にその値が保持されるオブジェクトが宣言されます。
名前空間のスコープ(クラスまたは関数定義の外)でオブジェクトまたは関数に適用すると、オブジェクトまたは関数はinternal linkageで宣言されます。 unnamed-namespaceがより良い代替手段を提供するため、この使用法はオブジェクトでは推奨されていません。
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 – PlasmaHH