静态数据成员的类内初始化

时间:2013-05-04 11:35:30

标签: c++ c++11

在C ++中,static成员可能不会在类体中初始化,但有以下例外:

    {li> static const整数类型成员
  • static constexpr字面类型的成员必须

你能解释一下这些例外的原因吗?

此外,这有:

  

即使在类体中初始化const static数据成员,该成员通常也应该在类定义之外定义。

我根本就没理解过。这个额外定义有什么意义?

试图在这里获得一些直觉。

1 个答案:

答案 0 :(得分:8)

为什么类定义中会有初始化器?

关于constconstexpr静态数据成员的两个例外:

[class.static.data] / 3

  

[注意:在这两种情况下,成员可能会出现在常量表达式中。 - 结束说明]

即。使用初始化程序,您可以在常量表达式中使用它们,例如

struct s
{
    static std::size_t const len = 10;
    int arr[len];
};
std::size_t const s::len;

如果未在类定义中初始化len,则编译器无法在下一行中轻松知道其值以定义arr的长度。

有人可能会争论允许在类定义中使用非const,非constexpr静态数据成员的初始值设定项,但这可能会干扰初始化顺序:

[basic.start.init] / 2

  

显式专用类模板的定义静态数据成员已经有序初始化。其他类模板静态数据成员(即,隐式或显式实例化的特化)具有无序初始化。 具有静态存储持续时间的其他非局部变量已订购初始化。

也就是说,包括初始化器的定义的顺序很重要。非本地对象的(动态)初始化顺序仅在翻译单元中定义,这是为什么必须有一个定义包括非const,非constexpr静态的初始化程序的另一个原因数据成员。


这个额外定义有什么意义?

IMO的评论已经回答了这个问题。您可能希望添加ODR,即作为具有外部链接的名称,静态数据成员必须(仅)在一个转换单元中定义(如果它是ODR使用的)。程序员可以选择这个翻译单元。