为什么需要在班级之外初始化非恒定静态变量

Why do non-constant static variables need to be initialized outside the class?

本文关键字:初始化 变量 静态 为什么      更新时间:2023-10-16

我知道,需要在类定义之外初始化非恒定静态变量,但是,是否有这样的原因?

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在声明的位置初始化)。对于非静态成员,我们使用constructormember initializer list进行初始化。但这意味着我们必须创建类的实例。

由于静态成员初始化不能取决于正在创建的实例,因此在声明成员的类之外完成。