为什么可以初始化非常量和静态常量成员变量,而不是静态成员变量
Why can one initialize non-const and static const member variables but not static member variables?
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 静态成员按照一般规则进行处理:它们需要单独的定义,并且应在定义点提供初始值设定项。
- 通过多个头文件使用常量变量
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 非常量变量只读位置的赋值
- 使用大量已知常量变量的正确方法
- 无法在具有常量变量大小的类中创建堆栈分配数组
- 这些语句是否等效(静态变量、常量变量和泛型)
- 包含常量变量并包含在多个文件中的标头的链接错误
- 我们如何修改常量变量的值
- 如何在模板类中设置静态常量变量
- 为什么常量变量是模板特殊化所必需的,而不是常量
- 如何在函数中传递常量变量?
- 定义常量变量的最佳方法
- C++ 声明常量变量,但推迟其初始化?
- 如何初始化具有常量变量的结构数组
- 使用常量变量作为维度将矩阵声明为类成员时出现编译器错误
- 使用指针 c++ 更改常量变量
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 为什么 lambda 对象中的局部变量是常量变量?
- 使用常量变量作为数组的大小
- 为许多类可能需要的所有常量变量制作独立的头文件是否是一种很好的做法?