C++ 为什么可以初始化非常量和静态常量成员变量,但不能初始化静态成员变量?

C++ 为什么可以初始化非常量和静态常量成员变量,但不能初始化静态成员变量?,c++,C++,为什么会这样?有人能给我解释一下这背后的原因吗?这与数据存储的位置有关。下面是一个细分: int:成员变量,存储在类实例存储的任何位置 常量int:与int相同 static const int:不需要存储,它可以在使用的地方简单地“内联” 静态int:程序中必须有一个存储位置…在哪里 由于静态int是可变的,因此它必须存储在某个实际位置,以便程序的一部分可以修改它,而另一部分可以看到该修改。但它不能存储在类实例中,所以它必须更像一个全局变量。那么为什么不把它变成一个全局变量呢?嗯,类声明通

为什么会这样?有人能给我解释一下这背后的原因吗?

这与数据存储的位置有关。下面是一个细分:

  • int:成员变量,存储在类实例存储的任何位置
  • 常量int:与int相同
  • static const int:不需要存储,它可以在使用的地方简单地“内联”
  • 静态int:程序中必须有一个存储位置…在哪里
由于静态int是可变的,因此它必须存储在某个实际位置,以便程序的一部分可以修改它,而另一部分可以看到该修改。但它不能存储在类实例中,所以它必须更像一个全局变量。那么为什么不把它变成一个全局变量呢?嗯,类声明通常在头文件中,头文件可能包含在多个翻译单元(.cpp文件)中。因此,头文件实际上会说“某处有一个int…”但存储需要放入相应的.cpp文件(就像一个全局变量)

最后,这实际上不是关于初始化,而是关于存储。您可以不使用初始值设定项,但在将其添加到.cpp文件之前,您仍然没有有效的程序:

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的引用将是未定义的,链接将失败。

静态常量成员变量的初始化可用于整型和枚举类型。这一特点自C++语言以来就存在于第一语言标准(C++ 98)中。需要在整型常量表达式(即编译时常量)中方便使用静态常量成员,这是该语言的一个重要特性。选择整型和枚举类型并以这种特殊方式进行处理的原因是整型常量通常在编译时上下文中使用,而编译时上下文不需要存储(无定义)该常量

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


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

此问题中提供的答案:@EdHeal真的吗?“静态常量int:不需要存储”@cdhowie:好的观点。上次我尝试了类似的方法,我得到了一个未定义的符号链接错误,就像使用非常量符号一样。但是,如果您从未使用过它的地址或与之相当的道德标准,那么您可能会在不定义存储的情况下逃之夭夭。我不是在对你是否应该做价值判断,但在普通平台上,你似乎可以。
int A::d; // initialize if you want to, default is zero