根据IBM C++ 知识中心的静态数据成员:
在类的成员列表中声明静态数据成员不是定义。您必须在命名空间范围内的类声明之外定义静态成员。
这是为什么?关于内存分配的原理图是什么?
这是语言的一条规则,称为单一定义规则。在程序中,每个静态对象(如果使用的话)必须定义一次,而且只定义一次。
类定义通常放在头文件中,包含在多个翻译单元中(即来自多个源文件)。如果标题中的静态对象声明是一个定义,那么您最终会得到多个定义,每个单元中包含一个包含标题的定义,这会违反规则。因此,它不是一个定义,您必须在其他地方准确提供一个定义。
原则上,该语言可以做它对内联函数所做的事情,允许将多个定义合并为一个定义。但事实并非如此,所以我们坚持这条规则。
这根本与内存分配无关。这是关于在链接的编译单元中具有单点定义。@Nick 也指出了这一点。
来自 Bjarne 的网站https://www.stroustrup.com/bs_faq2.html#in-class
一个类通常在头文件中声明,并且头文件通常包含在许多翻译单元中。但是,为了避免复杂的链接器规则,C++ 要求每个对象都有唯一的定义。如果 C++ 允许在类内定义需要作为对象存储在内存中的实体,则该规则将被打破。
从 C++17 开始,您现在可以在类中定义静态数据成员。请参阅cppreference:
静态数据成员可以内联声明。内联静态数据成员可以在类定义中定义,并且可以指定初始化器。它不需要类外定义:
struct X { inline static int n = 1; };