首页 文章

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

提问于
浏览
13

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

  • static 成员 const 整数类型 can

  • static 成员 constexpr 文字类型 must

你能解释为什么这些例外吗?

此外,这有:

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

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

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

1 回答

  • 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 wasn 't initialized in the class definition, the compiler couldn' t很容易在下一行知道它的值来定义 arr 的长度 .

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

    [basic.start.init] / 2

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

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


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

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

相关问题