24

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

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

这是为什么?关于内存分配的原理图是什么?

4

3 回答 3

29

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

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

原则上,该语言可以做它对内联函数所做的事情,允许将多个定义合并为一个定义。但事实并非如此,所以我们坚持这条规则。

于 2013-09-11T19:03:35.513 回答
12

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

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

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

于 2013-09-11T19:00:18.123 回答
8

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

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

struct X {
     inline static int n = 1; 
};
于 2018-04-03T18:48:35.880 回答