我们知道,类定义中的非内联静态数据成员是非定义声明,草稿源。
我们还知道,整数或枚举类型的非易失性非内联 const 静态数据成员可以指定初始化程序,草稿源
在这里表述一下:
如果非易失性非内联 const 静态数据成员为整型或枚举类型,则其在类定义中的声明可以指定括号或等号初始化器,其中每个作为赋值表达式的初始化器子句都是常量表达式 ([expr.const])。如果成员在程序中以 odr 方式使用 ([basic.def.odr]),则该成员仍应在命名空间范围内定义,并且命名空间范围定义不得包含初始化器。
因此我推测以下是有效的代码:
class A {
public:
static const int a = 1;
};
const int A::a = 3;
类定义内部的声明不是一个定义,因为它再次是类定义中非内联静态数据成员的声明。
在 Visual Studio 中,上面的代码返回了一个编译错误:
错误 C2374:'a':重新定义;多次初始化
问题:带有初始化器的非定义声明的实际含义是什么?为什么上面的代码无效,因为我们只有一个定义?
注意:这里的情况可能比较微妙,因为我想这是因为const,但重新定义错误引起了我的注意
您收到的错误消息有点误导——它实际上不是重复定义——但两者中只有一个可以初始化
a
。因此,您可以:...或者:
...但你不能在两个地方都有初始化程序。
还要注意,因为它是一个
const
,所以通常可以使用:...只要您使用它的方式不需要它有一个地址(例如,获取它的地址或通过引用传递它),您根本不需要实际定义。在这种情况下,它几乎相当于
#define
(您可以读取名称,但对于编译器来说,它几乎只是一个数字)——除了与不同#define
,它确实尊重范围等。