为什么可以初始化非const和静态const成员变量而不是静态成员变量?

时间:2014-10-04 05:35:31

标签: c++

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'

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

2 个答案:

答案 0 :(得分:2)

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

  • int:成员变量,存储在存储类实例的任何地方
  • const int:与int
  • 相同
  • static const int:不需要存储,只需"内联"使用的地方
  • static int:程序中必须有一个存储位置... where?

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

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

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

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

答案 1 :(得分:1)

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

为非静态成员提供初始值设定项的功能是一种新功能(适用于C ++ 11)。这是一个完全不同的功能,即使它在语法级别看起来相似。此类初始值设定项用作未由用户显式初始化的那些类成员的构造时初始值设定项。

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