在C ++中初始化私有静态数据成员的最佳方法是什么? 我在头文件中尝试了此操作,但它给了我奇怪的链接器错误:
class foo
{
private:
static int i;
};
int foo::i = 0;
我猜这是因为我无法从类外部初始化私有成员。 那么最好的方法是什么?
#1楼
对于以后这个问题的观众,我想指出,您应该避免monkey0506的建议 。
头文件用于声明。
头文件将针对每个直接或间接#includes
.cpp
文件进行一次.cpp
,并且任何函数之外的代码都将在程序初始化时运行在main()
之前。
通过输入: foo::i = VALUE;
在头文件中, foo:i
将为每个.cpp
文件分配值VALUE
(无论是什么),并且这些分配将在运行main()
之前以不确定的顺序(由链接器确定main()
进行。
如果我们在其中一个.cpp
文件中#define VALUE
为其他数字怎么办? 它将编译良好,并且在运行程序之前,我们将无法知道哪一个获胜。
绝对不要将执行的代码放入标头中,原因与您从未#include
.cpp
文件相同。
包含卫士(我同意您应该始终使用)来保护您免受不同的伤害:同一头文件在编译单个.cpp
文件时多次间接#include
d
#2楼
如果使用标题防护,也可以将分配包括在标题文件中。 我将这种技术用于我创建的C ++库。 获得相同结果的另一种方法是使用静态方法。 例如...
class Foo
{
public:
int GetMyStatic() const
{
return *MyStatic();
}
private:
static int* MyStatic()
{
static int mStatic = 0;
return &mStatic;
}
}
上面的代码具有不需要CPP /源文件的“好处”。 同样,这是我用于C ++库的一种方法。
#3楼
类声明应该在头文件中(如果未共享,则在源文件中)。
档案: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;
};
#4楼
对于变量 :
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;
};
#5楼
int foo::i = 0;
是用于初始化变量的正确语法,但是它必须位于源文件(.cpp)中,而不是标头中。
因为它是一个静态变量,所以编译器仅需要创建一个副本。 您必须在代码中的某些位置插入“ int foo:i”行,以告诉编译器将其放置在何处,否则会出现链接错误。 如果在标头中,则将在每个包含标头的文件中获得一个副本,因此请从链接器获取多个已定义的符号错误。
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3159416