2011-08-17 10 views
18

いくつかの静的データメンバーでクラスを作成しましたが、現在は「未定義参照」に関するエラーが発生しています。なぜこれは機能しませんか?私は間違って何をしていますか?スタティックメンバーへの未定義の参照を持つことは何を意味しますか?

は(注:これはStack Overflow's C++ FAQへのエントリであることを意味するこのフォームでのFAQを提供するという考えを批判したい場合は、the posting on meta that started all thisはそれを行うための場所となり、その質問に対する回答です。よくある質問アイデアが最初の場所で始まったC++ chatroom、で監視するので、あなたの答えは、アイデアを思い付いた人々によって読まを取得する可能性が非常に高いです。)あなたはで定義された静的メンバをインスタンス化する必要が

+0

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 – PlasmaHH

答えて

26

はこれを理解するには、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がより良い代替手段を提供するため、この使用法はオブジェクトでは推奨されていません。

+0

"特殊なケースとして、静的メンバー変数がconst整数または列挙型の場合、クラス定義の初期化子 "を参照してください。あなたはクラス*宣言*を意味しますか? –

+0

@SamGoldberg:いいえ - もし私が宣言_を言ったら、前方宣言(例えば 'class Example;')を参照しています。 _definition_では、クラスのメンバーを宣言するコードを意味します。 (はい、これらのメンバー自身がクラス定義の外で定義できますが、ここでは重要ではありません)。 – Mankarse

5

.cppファイル内のヘッダー。たとえば:

// foo.h 

class foo { 
    static int X; 
}; 


// foo.cpp 

#include "foo.h" 

int foo::X = 0; 
関連する問題