Why should I not initialize static variable in header?
所以,假设我有一个这样的标题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #ifndef BASECLASS_H #define BASECLASS_H class BaseClass { public: static int getX(){return x;} private: static int x; }; int BaseClass::x = 10; #endif |
我听说过很多次,我不应该在头中初始化静态变量,而应该在cpp中初始化。但是由于有警卫,所以应该只有一个baseclass::x的副本,所以我有点不明白为什么要放
1 | int BaseClass::x = 10; |
在CPP中。谢谢。
如果您在头中这样做,那么一旦您从多个cpp文件中包含它,就会出现多个定义错误。当您声明
1 | int BaseClass::x = 10; |
首先,您要定义符号baseclass::x;其次,您要告诉它初始值为10。根据一个定义规则,这在程序中只能发生一次。
如果考虑到预处理器实际上做了什么,也许更容易理解:它将所有包含的头文件的内容复制到cpp文件中,并将其传递给编译器。
现在假设您有:
1 2 3 4 5 6 7 8 9 | // In a.cpp #include <baseclass.h> // more code // In b.cpp #include <baseclass.h> // more code |
预处理器展开include后,两个文件都将包含:
1 | int BaseClass::x = 10; |
现在,一旦两个对象文件都传递给链接器,它将看到符号
现在,为了让它更明显,假设您将它放在一个头文件中:
1 | int aGlobalVariable = 10; |
然后将它包含在两个不同的cpp文件中,这两个文件都应该链接到一个可执行文件中。如果从链接器的角度来看,它实际上与您的示例没有任何不同。
为什么这不是类声明的问题?
声明和定义之间有区别。只有后者才会引起问题。例如,以下所有内容都是声明:
extern int a; void foo(int a); class Foo { int bar(); };
鉴于这些定义:
int a; int b = 10; void foo(int a) { /*..*/ } int Foo::bar() { /*...*/ }
只要有一个(并且只有一个)定义,您可以拥有任意多的声明,并且链接器将确保它们都引用相同的函数或内存位置。
现在上课怎么样?类只能声明,而必须定义其成员函数和静态成员。同样,每个定义只能存在一次。
成员函数和静态成员实际上在程序的地址空间中只存在一次,而类的每个对象都存在普通成员(实例变量)。
回到您的具体问题:静态成员基本上只是全局变量,但作用域是类的名称。
希望这能帮你解决问题!
保护不会阻止多个源文件中的多个副本。它们只在一个源文件中阻止多个副本。
如果您有多个
因为如果您在头中初始化它,那么如果您多次包含头,它可能会在多个位置被定义。这将导致链接器错误