2016-10-02 120 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:旧的函数声明语法'非常有限的适用范围完全由新的语法覆盖。使用两种语法来完成同样的事情是愚蠢的。我不同意可读性;相反,旧的语法糟透了。可读性,特别是对于返回类型更长的模板表达式(也需要限定具有类作用域的返回类型)。 –