在C ++中初始化私有静态数据成员的最佳方法是什么? 我在头文件中尝试了此操做,但它给了我奇怪的连接器错误: 函数
class foo { private: static int i; }; int foo::i = 0;
我猜这是由于我没法从类外部初始化私有成员。 那么最好的方法是什么? spa
对于之后这个问题的观众,我想指出,您应该避免monkey0506的建议 。 code
头文件用于声明。 get
头文件将针对每一个直接或间接#includes
.cpp
文件进行一次.cpp
,而且任何函数以外的代码都将在程序初始化时运行在main()
以前。 编译器
经过输入: foo::i = VALUE;
在头文件中, foo:i
将为每一个.cpp
文件分配值VALUE
(不管是什么),而且这些分配将在运行main()
以前以不肯定的顺序(由连接器肯定main()
进行。 it
若是咱们在其中一个.cpp
文件中#define VALUE
为其余数字怎么办? 它将编译良好,而且在运行程序以前,咱们将没法知道哪个获胜。 io
绝对不要将执行的代码放入标头中,缘由与您从未#include
.cpp
文件相同。 编译
包含卫士(我赞成您应该始终使用)来保护您免受不一样的伤害:同一头文件在编译单个.cpp
文件时屡次间接#include
d class
若是使用标题防御,也能够将分配包括在标题文件中。 我将这种技术用于我建立的C ++库。 得到相同结果的另外一种方法是使用静态方法。 例如... 变量
class Foo { public: int GetMyStatic() const { return *MyStatic(); } private: static int* MyStatic() { static int mStatic = 0; return &mStatic; } }
上面的代码具备不须要CPP /源文件的“好处”。 一样,这是我用于C ++库的一种方法。
类声明应该在头文件中(若是未共享,则在源文件中)。
档案:foo.h
class foo { private: static int i; };
可是初始化应该在源文件中。
档案:foo.cpp
int foo::i = 0;
若是初始化在头文件中,则每一个包含头文件的文件都将具备静态成员的定义。 所以,在连接阶段,您将获得连接器错误,由于初始化变量的代码将在多个源文件中定义。 static int i
的初始化必须在任何函数以外完成。
注意: Matt Curtis:指出,若是静态成员变量为const int类型(例如int
, bool
, char
),则C ++容许简化上述操做。 而后,您能够直接在头文件的类声明中声明和初始化成员变量:
class foo { private: static int const i = 42; };
对于变量 :
foo.h:
class foo { private: static int i; };
foo.cpp:
int foo::i = 0;
这是由于程序中只能有一个foo::i
实例。 它有点像头文件中的extern int i
和源文件中的int i
。
对于常量 ,能够将值直接放在类声明中:
class foo { private: static int i; const static int a = 42; };
int foo::i = 0;
是用于初始化变量的正确语法,可是它必须位于源文件(.cpp)中,而不是标头中。
由于它是一个静态变量,因此编译器仅须要建立一个副本。 您必须在代码中的某些位置插入“ int foo:i”行,以告诉编译器将其放置在何处,不然会出现连接错误。 若是在标头中,则将在每一个包含标头的文件中得到一个副本,所以请从连接器获取多个已定义的符号错误。