3 回答
TA贡献1780条经验 获得超1个赞
从根本上讲,这是因为静态成员必须精确地定义在一个翻译单元中,以便不违反单一定义规则。如果语言允许类似以下内容:
struct Gizmo
{
static string name = "Foo";
};
然后name将在#include该头文件的每个转换单元中定义。
C ++确实允许您在声明中定义不可分割的静态成员,但是您仍然必须在单个翻译单元中包含一个定义,但这只是一个捷径或语法糖。因此,这是允许的:
struct Gizmo
{
static const int count = 42;
};
只要a)表达式是const整数或枚举类型,b)可以在编译时对表达式求值,并且c)仍然存在不违反一个定义规则的定义:
文件:gizmo.cpp
#include "gizmo.h"
const int Gizmo::count;
TA贡献1765条经验 获得超5个赞
在C ++中,自开始以来,初始化器的存在是对象定义的专有属性,即,带有初始化器的声明始终是定义(几乎总是)。
如您所知,C ++程序中使用的每个外部对象都必须在一个翻译单元中定义一次,并且只能定义一次。允许类内初始化程序用于静态对象将立即违反此约定:初始化程序将进入头文件(通常在类定义所在的位置),从而生成同一静态对象的多个定义(每个包含头文件的翻译单元一个定义) )。当然,这是不可接受的。因此,静态类成员的声明方法完全是“传统”的:您仅在头文件中声明它(即不允许初始化器),然后在您选择的翻译单元中定义它(可能使用初始化器) )。
此规则的一个例外是整数或枚举类型的const静态类成员,因为此类条目可以用于整数常量表达式(ICE)。ICE的主要思想是在编译时对其进行评估,因此不依赖于所涉及对象的定义。这就是为什么整数或枚举类型可能会出现此异常的原因。但是对于其他类型,这只会与C ++的基本声明/定义原理相矛盾。
- 3 回答
- 0 关注
- 1175 浏览
添加回答
举报