为什么不能在正文或头文件中的类中初始化静态成员?

sky*_*oor 0 c++

任何机构能否为我提供任何理由?

如果我们这样做,结果是什么?编译错误?

Ara*_*raK 5

这只是它自身语言的一个限制.希望,当C++ 0x成为现实时,这种限制将会消失.

我认为这个页面提供了一个很好的理由:

在类中使用静态数据成员的最棘手的后果之一是它必须在源文件中仅在类定义之外初始化一次.这是因为编译器通常会多次看到头文件.如果编译器多次遇到变量的初始化,则很难确保变量被正确初始化.因此,在整个程序中只允许一次静态初始化.

  • 要扩展一点,如果在多个位置初始化相同的静态,则链接器必须验证它们是否都初始化为相同的值.鉴于初始化表达式可能是任意复杂的(包括函数调用)而不是可编译的编译时,这是不可能的. (2认同)

Joh*_*ing 5

问题是静态初始化不仅仅是初始化,它也是定义.举个例子:

hacks.h:

class Foo
{
public:
    static std::string bar_;
};

std::string Foo::bar_ = "Hello";

std::string GimmeFoo();
Run Code Online (Sandbox Code Playgroud)

main.cpp:

#include <string>
#include <sstream>
#include <iostream>

#include "hacks.h"

using std::string;
using std::ostringstream;
using std::cout;

int main()
{

    string s = GimmeFoo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

foo.cpp:

#include <string>
#include <sstream>
#include <iostream>

#include "hacks.h"

using std::string;
using std::ostringstream;
using std::cout;

string GimmeFoo()
{
    Foo foo;
    foo;
    string s = foo.bar_;

    return s;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您无法Foo::bar_在标头中初始化,因为它将在每个#includehacks.h的文件中分配.所以Foo.bar_内存中会有2个实例- 一个在main.cpp中,一个在foo.cpp中.

解决方案是在一个地方分配和初始化:

foo.cpp:

...
std::string Foo::bar_ = "Hello";
...
Run Code Online (Sandbox Code Playgroud)