我知道你通常在.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的向量。当然,任何静态成员都必须在程序初始化时分配内存,那么编译器为什么不使用默认的构造函数呢?
答案 0 :(得分:16)
不是关于初始化,而是定义。 或者更确切地说:它是关于知道哪个编译单元(.cpp)将保存对象(必须在某个地方唯一定义)
所以,所需要的只是将定义放在某处,在一个独特的地方,即cpp,让编译器知道当类的静态对象时被称为,它在那里定义,而不是其他地方。 (如果你试图在标题中定义你的静态,那么包含这个标题的每个cpp都会有一个定义,无法知道应该在哪里定义 - 并且如果你需要它,你可以手动初始化)
答案 1 :(得分:9)
您正在从单个编译单元的角度来看它。
但语言必须假设可能存在多个编译单元。那么现在哪个编译单元是创建的静态对象?基本上,编译器不允许做出决定,工程师必须做出决定。
答案 2 :(得分:3)
undefined reference to 'A::x'
不是编译器错误;这是一个链接器错误。这意味着在任何链接在一起形成程序的翻译单元中找不到A::x
的定义。静态成员变量具有外部链接,必须在一个转换单元中定义。任何具有外部链接的东西都不会有编译器生成的定义,除非你写一个。
答案 3 :(得分:2)
你称之为初始化的是定义。您需要在某处定义静态成员。类中的部分只是一个声明。
这主要是因为在标题内部定义会导致很大的问题(因为您不能将该标题包含在多个翻译单元中而不会导致多个定义)。