为什么需要在班级之外初始化非恒定静态变量
Why do non-constant static variables need to be initialized outside the class?
我知道,需要在类定义之外初始化非恒定静态变量,但是,是否有这样的原因?
class A {
static int x = 0 // compile error;
static int y;
};
int A::y = 0; // fine
本质上是因为x
独立于创建的A
的实例数。
因此,需要在某个地方定义x
的存储 - 您不能依靠A
的实例来执行此操作,这就是
A::x = 0;
在一个翻译单元中,
存在const
限定符时,静态变量可以视为恒定表达式。在类定义中将其初始化为该效果。这只是一个恒定的值,甚至可能不需要任何存储。
,但在另一种情况下,这不是一个恒定的表达。它绝对需要存储。正如@bathsheba指出的那样,仅需在一个翻译单元(Pre-C 17)中定义它。一般而言,包含初始化器的声明也是一个定义。因此,当声明时无法初始化它。
从C 17开始,该变量可以是内联变量。因此,实际上可以将定义包括在类声明
中class A {
static inline int x = 0;
};
,编译器将把所有这些声明整理成相同的存储。
经过一项小型研究,发现(来自Bogotobogo):
我们无法在类声明中初始化静态成员变量。这是因为声明是对内存的分配方式的描述,但不是分配内存。我们通过使用该格式创建对象来分配和初始化内存。
在静态类成员的情况下,我们独立初始化静态成员,并在班级声明之外单独的语句。那是因为静态类成员是单独存储的,而不是作为对象的一部分存储。
类声明中静态数据成员初始化的例外是静态数据成员是否是积分或枚举类型的const。
我的看法是..
静态成员作为类的成员存在,而不是类的每个对象中的实例。
当您在类声明内的静态变量初始化为概念时,它将在类的每个创建对象/实例的创建中重新定位(不是实际行为),[由于类声明是类构造的每个新对象的蓝图]。
,我们知道这不应该是静态成员的行为,因此该成员的初始化不在类声明之外。
我发现这种解释更直观,但正式的解释仍然是第一个。
除了其他人所说的话,当前没有位置(前C 11),您可以在其中初始化静态成员(因为成员(因为静态和非静态都可以't在声明的位置初始化)。对于非静态成员,我们使用constructor
或member initializer list
进行初始化。但这意味着我们必须创建类的实例。
由于静态成员初始化不能取决于正在创建的实例,因此在声明成员的类之外完成。
- 初始值设定项列表是否只接受使用相同类型的值初始化变量?
- 在 C++ 中访问 lambda 捕获初始化变量
- 为什么C++不支持对未初始化变量进行智能分析?
- 使用 clang++ 和 g++ 在C++中初始化变量
- C++使用 lambda 初始化变量
- 如何在初始化列表中的构造函数之后初始化变量/对象?
- C++ - 输出与初始化变量不同?
- C++/Win32 构造函数不使用从对话框获取的字符串初始化变量
- 在C++中,为什么int可以使用new运算符初始化变量,而double不能
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- C++ 中的初始化变量
- C++中未初始化变量的值
- 如何在需要提及需要循环声明的其他类的类中初始化变量?
- 我想知道在构造函数中初始化变量时的生命周期
- 读取恰好具有良好值的未初始化变量
- 如何在 getter 的父类中初始化变量的情况下访问子类中的变量
- 为什么在 c++ 中有多种初始化变量的方法
- 没有参数的默认构造函数是否总是初始化变量?
- 是否可以使用 lambda 初始化变量(删除复制 ctor 时)
- 使用构造函数跳闸UB的新放置后使用初始化变量