Dai*_*ner 0 c++ static-members
为什么当数据成员在类内初始化且没有类外定义时,C++ 不允许获取静态数据成员的地址?在这种情况下,静态成员的存储空间是如何分配的?
下面的最小程序演示了这个问题。
#include <iostream>
class Test {
public:
static const int a = 99; // how is the storage allocated for Test::a??
};
// const int Test::a;
int main() {
std::cout << Test::a << '\n'; // OK, print 99
const int* ptr = &Test::a; // Linker error, undefined reference to Test::a
}
Run Code Online (Sandbox Code Playgroud)
如果我取消注释该行const int Test::a,那么程序就可以正常工作。
这一行是一个声明:
static const int a = 99;
Run Code Online (Sandbox Code Playgroud)
这不是一个定义。对于要分配的存储,您需要一个定义。这就是您的注释行发挥作用的地方。
Test::a即使它没有定义,您也可以使用,因为它被视为编译时常量。一般来说,static const T变量(其中T是普通类型)一旦被常量初始化就必须可以在常量表达式中使用。
请注意,您可以同时获得两种行为(编译时常量和带有地址的变量):
class Test {
public:
static const int a = 99;
};
const int Test::a;
template<int i>
struct Templated {};
int main() {
const int* ptr = &Test::a;
Templated<Test::a> a;
}
Run Code Online (Sandbox Code Playgroud)
并说明常量初始化点:
class Test {
public:
static const int a;
};
template<int i>
struct Templated {};
// does not compile because Test::a is *not yet* usable in a constant expression
Templated<Test::a> global;
const int Test::a = 99;
int main() {
const int* ptr = &Test::a;
Templated<Test::a> a;
}
Run Code Online (Sandbox Code Playgroud)