2011-08-17 81 views
18

我剛剛用一些靜態數據成員編寫了一個類,但現在我收到有關「未定義引用」的錯誤。爲什麼這不起作用?我究竟做錯了什麼?對靜態成員有一個未定義的引用是什麼意思?

(注意:這是爲了是Stack Overflow's C++ FAQ條目如果你想批評這種形式提供幫助的想法,那麼the posting on meta that started all this會做到這一點的地方回答這個問題是監測的C++ chatroom,那裏的FAQ想法擺在首位開始了,所以你的答案是很可能得到那些誰的想法來到了閱讀。)

+0

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 – PlasmaHH 2011-08-17 12:31:10

回答

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

作爲一個特殊的情況下,如果靜態成員變量是一個常量整數或枚舉類型,那麼其可以具有在類定義的初始化劑:

//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整型或枚舉類型,那麼它可以有一個類定義中的初始化程序「。你在這裏指的是class *聲明嗎? – 2013-08-06 16:50:50

5

你必須實例中定義靜態成員.cpp文件中的頭文件。例如:

// foo.h 

class foo { 
    static int X; 
}; 


// foo.cpp 

#include "foo.h" 

int foo::X = 0; 
相關問題