2016-10-02 61 views
0

我試圖通過修改靜態數據成員來算一個類的實例的數量:修改靜態數據成員


class C 
{ 
public: 
    static unsigned int i; 
    C(){i++;} 
}; 

這顯示了一個錯誤:
Main.obj:錯誤LNK2001:無法解析的外部符號「public:static unsigned char C :: i」(?i @ C @@ 2EA)

請通過編輯此代碼以適當運行或者讓我知道此問題的解決方案使用任何全局變量。
您的回答將不勝感激。
謝謝。

+0

只需在類聲明後添加'unsigned int C :: i = 0;'就可以工作了 –

+0

另外,http://stackoverflow.com/questions/15845745/lnk2001-error-when-accessing-static-variables- c,http://stackoverflow.com/questions/16049306/error-lnk2001-unresolved-external-symbol-private-static-class和許多其他許多人。 – AnT

回答

0

分配給的直接靜態數據成員需要定義。基本上定義分配內存。是這樣的:

class C 
{ 
private: 
    static int i; // pure declaration 

public: 
    static auto n_instances() -> int { return i; } 
    ~C() { --i; } 
    C(){ ++i; } 
    C(C const&) { ++i; } 
}; 

int C::i; // definition 

在頭文件是不切實際的(如果報頭在多個翻譯單位使用這將是違反了一個定義規則,與鏈接器抱怨),這樣的話就可以使用以下技術:

class C 
{ 
private: 
    static auto n() 
     -> int& 
    { 
     static int the_count = 0; 
     return the_count; 
    } 
public: 
    static auto n_instances() -> int { return n(); } 
    ~C() { --n(); } 
    C(){ ++n(); } 
    C(C const&) { ++n(); } 
}; 

還有其他方法可以做到這一點,包括模板技巧和C++ 17個inline數據。

我選擇使用int,而不是unsigned因爲int有利於整數數字,而unsigned是好位層次的東西,而不是相反。

聲明:代碼沒有被編譯器觸及。

+0

爲什麼'auto'的東西代替了更短,更容易閱讀'static int&n(){static int n;返回n; ''? – 6502

+0

@Cheers:謝謝,這回答我的問題,並在許多類似的情況下有幫助。 –

+0

@ 6502:舊的函數聲明語法'非常有限的適用範圍完全由新的語法覆蓋。使用兩種語法來完成同樣的事情是愚蠢的。我不同意可讀性;相反,舊的語法糟透了。可讀性,特別是對於返回類型更長的模板表達式(也需要限定具有類作用域的返回類型)。 –