为什么需要在类外部定义静态数据成员

Why does a static data member need to be defined outside of the class?

本文关键字:定义 静态 数据成员 外部 为什么      更新时间:2023-10-16

根据 IBM C++ 知识中心的静态数据成员:

类的成员列表中静态数据成员的声明不是定义。必须在命名空间范围内定义类声明之外的静态成员。

为什么?关于内存分配,这背后的原理是什么?

这是语言的规则,称为一个定义规则。在程序中,每个静态对象(如果使用)必须定义一次,并且只能定义一次。

类定义通常位于头文件中,包含在多个翻译单元中(即来自多个源文件)。如果标头中的静态对象的声明是一个定义,那么您最终会得到多个定义,每个单元中包含一个包含标头的定义,这将破坏规则。因此,它不是一个定义,您必须在其他地方提供确切的一个定义。

原则上,该语言可以执行内联函数的功能,允许将多个定义合并为一个定义。但它没有,所以我们坚持这个规则。

这根本不是关于内存分配部分。这是关于在链接的编译单元中具有单点定义。 @Nick也指出了这一点。

来自Bjarne的网站 https://www.stroustrup.com/bs_faq2.html#in-class

类通常在头文件中声明,头文件 通常包含在许多翻译单元中。但是,要避免 复杂的链接器规则,C++要求每个对象都有一个唯一的 定义。如果允许在课堂上C++该规则将被打破 定义需要作为对象存储在内存中的实体。

从 C++17 开始,您现在可以在类中定义静态数据成员。请参阅 cpp 首选项:

静态数据成员可以内联声明。内联静态数据 成员可以在类定义中定义,并且可以指定 初始 化。它不需要类外定义:

struct X {
     inline static int n = 1; 
};

根据静态数据成员的定义,我们只能定义一次静态变量(即仅在类中),并且它由类的每个实例共享。此外,可以在没有任何对象的情况下访问静态成员。

根据 OOPS 指南,编译器不会将内存分配给类,而是将内存分配给对象,但静态成员独立于对象,因此为了将内存分配给静态变量,我们在类之外定义静态数据成员,这就是为什么一旦声明了这个变量,它就会一直存在到程序执行。通常,静态成员函数用于修改静态变量。