2013-10-13 32 views
-2

以下的靜態函數使用一個靜態變量編譯細跟克++:如何在一個結構

struct acounter { 

    long static counter; 

    void static create() { //reset or create the counter 
    counter=0; 
    } 

    void static count() { //the counter changes its internal value. 
    counter=counter + 1; 
    } 

}; 


int main(int argc, char *argv[]){ //compiles and executes! 
    //do some random stuff... 
    return 0; 
} 

的問題是:一旦予添加「acounter ::創建();」或「acounter :: count();」到主循環,我得到一個錯誤:

undefined reference to `acounter::counter'

但我定義「計數器」,甚至初始化它。問題是什麼?

(PS我只能用靜態的功能,因爲我有對付回調後 - 的想法是使用整個結構只在其全球範圍內,而無需創建實例。)

回答

2

靜態類成員必須定義爲以及聲明。雖然我們可以,但我們可以初始化靜態成員到正確的值,所以不再需要「創建」 - 但我們可以有一個「重置」邏輯。另外,如果你真的通過靜態函數暴露邏輯,計數器本身應該是私有的。

最後,作爲樣式,static關鍵字通常放在類型名稱之前。這是一個有趣的問題,但它是一個相當重要的屬性,應該能夠在查看類定義時快速告訴靜態和非靜態成員。

struct acounter 
{ 
private: 
    static long counter; 
public: 
    static void reset() { counter = 0; } 
    static void count() { ++counter; } 
}; 

long acounter::counter = 0; // definition and initial value 

int main() 
{ 
    acounter::count(); 
} 
+0

我認爲這是常見的做法,而不是味道的問題,首先放置關鍵字,如「靜態」。 – Chiffa

+0

@Chiffa:好吧,我也會這麼說,但我不能爲所有人說話。我認爲它絕對更具可讀性,而且我從來沒有在「真實」代碼庫中看到過其他任何東西...... –

+0

謝謝,完美的答案 - 一條額外的代碼就完成了。 – Kenobi

0

將這個成*.cpp

long acounter::counter; 

注:你可能想將其初始化爲好,例如:

long acounter::counter = 0; 

static,但非const數據成員應該定義在類/結構定義的外部,並且在包含類/結構的名稱空間內定義。通常的做法是在翻譯單元(*.cpp)中定義它,因爲它被認爲是一個實現細節。

從C++標準的第9.4.2節提取物:

The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition.

還有另一種方式。只有staticconst整型可以聲明,並在同一時間(類/結構定義中)定義:

class Example { 
public: 
    static const long x = 101; 
}; 

在這種情況下,你並不需要添加x定義,因爲它已經被定義在類內部/結構定義。在你的情況下,long是整數類型,但不是const,所以你不能選擇這種方法。

相關問題