为什么需要在类外部初始化非常量静态变量?

Bla*_*sco 17 c++ static

我知道非常量静态变量需要在类定义之外进行初始化,但有没有理由呢?

class A {
    static int x = 0 // compile error;
    static int y;
};

int A::y = 0; // fine
Run Code Online (Sandbox Code Playgroud)

Bat*_*eba 18

本质上,它是因为x独立的数量存在情况下A所创建.

因此x需要在某处定义存储- 你不能依赖于A这样做的实例,而这就是它

A::x = 0;
Run Code Online (Sandbox Code Playgroud)

在一个翻译单元中,确实如此.

  • 看似合乎逻辑,但您可以对静态成员方法使用相同的推理,并且仍然可以在类中定义它们.即使跨多个编译单元获取静态成员方法的地址也会产生相同的地址,因此链接器以某种方式设法"合并"静态成员方法的多个定义.那么为什么链接器不能用于静态数据成员呢?(注意:这主要是因为它需要在类外定义,与初始化本身无关). (8认同)
  • @Patrick这可能是引入内联变量的原因之一. (2认同)

Sto*_*ica 18

当存在const限定符时,静态变量可以被视为常量表达式.在类定义中初始化它会产生这种效果.它只是一些不变的价值,甚至可能不需要任何存储空间.

但在另一种情况下,它不是一个恒定的表达.它肯定需要存储.正如@Bathsheba指出的那样,它只需要在一个翻译单元中定义(前C++ 17).一般来说,包含初始值设定项的声明也是一个定义.因此它在声明时无法初始化.


从C++ 17开始,该变量可以是内联变量.因此,该定义实际上可以包含在类声明中

class A {
  static inline int x = 0;
};
Run Code Online (Sandbox Code Playgroud)

并且编译器会将所有这些声明理清为相同的存储.