【问题标题】:Why can one initialize non-const and static const member variables but not static member variables?为什么可以初始化非 const 和静态 const 成员变量,但不能初始化静态成员变量?
【发布时间】:2014-10-04 05:35:31
【问题描述】:
struct A
{
    int a = 5;               //OK
    const int b = 5;         //OK 
    static const int c = 5;  //OK 
    static int d = 5;        //Error!
} 



error: ISO C++ forbids in-class initialization of non-const static member 'A::d'

为什么会这样?有人可以向我解释这背后的原因吗?

【问题讨论】:

标签: c++


【解决方案1】:

这与数据的存储位置有关。这是一个细分:

  • int:成员变量,存放类实例的任何地方
  • const int:与 int 相同
  • static const int:不需要存储,在使用的地方可以简单地“内联”
  • static int:这在程序中必须有一个单独的存储位置...在哪里?

由于静态 int 是可变的,它必须存储在某处的实际位置,以便程序的一部分可以修改它,而另一部分可以看到该修改。但它不能存储在类实例中,所以它必须更像是一个全局变量。那么为什么不把它变成一个全局变量呢?好吧,类声明通常在头文件中,并且一个头文件可能在多个翻译单元(.cpp 文件)中#included。因此,头文件有效地表明“有一个 int ......某处”。但是存储需要放到对应的.cpp文件中(像全局变量一样)。

最后,这并不是真正的初始化,而是存储。您可以不使用初始化程序,在将其添加到 .cpp 文件之前,您仍然没有有效的程序:

int A::d; // initialize if you want to, default is zero

如果没有这个,对静态 int 的引用将是未定义的并且链接将失败。

【讨论】:

  • "static const int: 不需要存储"
  • @cdhowie:好点。上次我尝试这样的事情时,我得到了一个未定义的符号链接错误,就像你使用非常量的一样。但是,如果您从不使用它的地址或道德等价物,您可能会在没有在任何地方定义存储的情况下逃脱。我不会对您是否应该做出价值判断,但在通用平台上似乎可以。
【解决方案2】:

静态 const 成员变量的初始化可用于整型和枚举类型。自第一个语言标准 (C++98) 以来,此功能就存在于 C++ 中。需要方便在整数常量表达式中使用静态常量成员(即作为编译时常量),这是该语言的一个重要特性。整数和枚举类型被单独列出并以这种特殊方式处理的原因是整数常量通常用于编译时上下文,它不需要存储(无需定义)常量。

为非静态成员提供初始化程序的能力是一个新的(对于 C++11)特性。这是一个完全不同的特性,尽管它在语法级别上看起来很相似。此类初始化器用作那些未由用户显式初始化的类成员的构造时初始化器。

换句话说,将这两个功能(静态和非静态成员的初始化程序)混为一谈是不正确的。这两个特点是完全不同的。它们基于完全不相关的内部机制。您的问题基本上适用于第一个功能:非 const 静态成员为什么不能在课堂上初始化?它基本上是一个 C++98 问题,最可能的答案是,从来没有任何理由以这种特殊的方式处理非常量静态成员。非常量静态成员按照一般规则处理:它们需要单独定义,并且应在定义时提供初始化程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 2014-09-08
    相关资源
    最近更新 更多