我们知道类定义中的非内联静态数据成员是非定义声明,草稿源。
我们还有一个整型或枚举类型的非易失性非内联 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':重新定义;多重初始化
问题: 带初始值设定项的非定义声明的实际含义是什么? 为什么上面的代码无效,因为我们只有一个定义?
Obs:这里的情况可能很微妙,因为我认为const,但重新定义错误引起了我的注意
您收到的错误消息有点欺骗性——它并不是真正的重复定义——但两者中只有一个可以初始化
a
。所以你可以选择:
class A {
public:
static const int a = 1;
};
const int A::a;
...或:
class A {
public:
static const int a;
};
const int A::a = 3;
...但是你不能在两个地方都有初始化器。
另请注意,由于它是
static const
,因此您通常可以只使用:
class A {
public:
static const int a = 1;
};
...只要您不以要求它具有地址的方式使用它(例如,获取其地址或通过引用传递它),您根本不需要实际的定义。