非内联静态数据成员在声明和定义方面如何表现?

问题描述 投票:0回答:1

我们知道类定义中的非内联静态数据成员是非定义声明,草稿源

我们还有一个整型或枚举类型的非易失性非内联 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,但重新定义错误引起了我的注意

c++ class static
1个回答
0
投票

您收到的错误消息有点欺骗性——它并不是真正的重复定义——但两者中只有一个可以初始化

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;
};

...只要您不以要求它具有地址的方式使用它(例如,获取其地址或通过引用传递它),您根本不需要实际的定义。

© www.soinside.com 2019 - 2024. All rights reserved.