为什么可以初始化非常量和静态常量成员变量,而不是静态成员变量

Why can one initialize non-const and static const member variables but not static member variables?

本文关键字:常量 变量 静态成员 成员 静态 初始化 非常 为什么      更新时间:2023-10-16
struct A
{
    int a = 5;               //OK
    const int b = 5;         //OK 
    static const int c = 5;  //OK 
    static int d = 5;        //Error!
} 

error: ISO C++ forbids in-class initialization of non-const static member 'A::d'

为什么会这样?有人可以向我解释这背后的原因吗?

它与数据的存储位置有关。 以下是细分:

  • int:成员变量,存储在存储类实例的任何位置
  • 常量 int:与 int 相同
  • static const int:不需要存储,它可以简单地"内联"使用的地方
  • 静态 int:这必须在程序中有一个存储位置...哪里?

由于 static int 是可变的,因此它必须存储在某个实际位置,以便程序的一部分可以修改它,而另一部分可以看到该修改。 但它不能存储在类实例中,所以它必须更像一个全局变量。 那么为什么不把它变成一个全局变量呢? 类声明通常位于头文件中,头文件可能 #included 多个翻译单元(.cpp 个文件(。 因此,头文件有效地说"有一个int...某处。 但是存储需要放入相应的.cpp文件中(如全局变量(。

最后,这不是真正的初始化,而是存储。 您可以省略初始值设定项,在将其添加到.cpp文件之前,您仍然没有有效的程序:

int A::d; // initialize if you want to, default is zero

否则,对静态 int 的引用将未定义,链接将失败。

静态 const 成员变量的初始化可用于整型和枚举类型。自第一个语言标准 (C++98( 以来,此功能就存在于C++。需要它来促进在整数常量表达式中使用静态常量成员(即作为编译时常量(,这是该语言的一个重要特征。整型和枚举类型被挑出来并以这种特殊方式处理的原因是,整型常量通常用于编译时上下文中,而编译时上下文不需要存储(无定义(常量。

为非静态成员提供初始值设定项的功能是一项新的 (对于 C++11( 功能。这是一个完全不同的功能,即使它在语法级别看起来很相似。此类初始值设定项用作用户未显式初始化的类成员的构造时初始值设定项。

换句话说,将这两个功能(静态和非静态成员的初始值设定项(混为一谈是不正确的。这两个功能是完全不同的。它们基于完全不相关的内部机制。您的问题基本上应用了第一个功能:为什么不能在类中初始化非常量静态成员?这基本上是一个 C++98 的问题,最有可能的答案是,从来没有任何理由以如此特殊的方式对待非常量静态成员。非 const 静态成员按照一般规则进行处理:它们需要单独的定义,并且应在定义点提供初始值设定项。