为什么_have_初始化C ++静态成员变量?

时间:2010-11-04 15:09:24

标签: c++ static static-members

我知道你通常在.cpp文件中初始化一个静态成员变量。但我的问题是:为什么 到?

这是一个例子:

#include <vector>

using namespace std;

class A {
    public:
        static vector<int> x;
};

main() {
    int sz = A::x.size();
}

#include <vector> using namespace std; class A { public: static vector<int> x; }; main() { int sz = A::x.size(); }

这会产生编译器错误:

但是,这个: undefined reference to 'A::x'

#include <vector>

using namespace std;

class A {
    public:
        static vector<int> x;
};

// Initialize static member
vector<int> A::x;

main() {
    int sz = A::x.size();
}

编译并运行良好。

我可以理解我是否使用默认构造函数之外的其他东西初始化向量,但我不是。我只想创建一个大小为0的向量。当然,任何静态成员都必须在程序初始化时分配内存,那么编译器为什么不使用默认的构造函数呢?

4 个答案:

答案 0 :(得分:16)

不是关于初始化,而是定义。 或者更确切地说:它是关于知道哪个编译单元(.cpp)将保存对象(必须在某个地方唯一定义)

所以,所需要的只是将定义放在某处,在一个独特的地方,即cpp,让编译器知道当类的静态对象时被称为,它在那里定义,而不是其他地方。 (如果你试图在标题中定义你的静态,那么包含这个标题的每个cpp都会有一个定义,无法知道应该在哪里定义 - 并且如果你需要它,你可以手动初始化)

答案 1 :(得分:9)

您正在从单个编译单元的角度来看它。

但语言必须假设可能存在多个编译单元。那么现在哪个编译单元是创建的静态对象?基本上,编译器不允许做出决定,工程师必须做出决定。

答案 2 :(得分:3)

undefined reference to 'A::x'不是编译器错误;这是一个链接器错误。这意味着在任何链接在一起形成程序的翻译单元中找不到A::x的定义。静态成员变量具有外部链接,必须在一个转换单元中定义。任何具有外部链接的东西都不会有编译器生成的定义,除非你写一个。

答案 3 :(得分:2)

你称之为初始化的是定义。您需要在某处定义静态成员。类中的部分只是一个声明。

这主要是因为在标题内部定义会导致很大的问题(因为您不能将该标题包含在多个翻译单元中而不会导致多个定义)。