2014-10-04 189 views
0
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' 

这是为什么?有人能向我解释这背后的原因吗?为什么初始化非const和静态const成员变量而不是静态成员变量?

+0

static - 阅读字典http://dictionary.reference.com/browse/static – 2014-10-04 05:51:33

+0

在这个问题中提供的答案:http:// stackoverflow。com/questions/20310000/error-iso-c-forbids-class-non-const-static-member的初始化 – balajeerc 2014-10-04 05:53:28

回答

1

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

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

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

最后,这不是关于初始化,而是存储。你可以离开过初始化和你仍旧没有一个有效的程序,直到您添加到您的.cpp文件:

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

没有这一点,在静态INT的引用将是不确定的和链接将失败。

+0

*“static const int:不需要存储”* < - 这是不对。如果你将一个指针指向一个静态const成员呢?指针应该指向什么? – cdhowie 2014-10-04 06:37:30

+0

@cdhowie:好点。最后一次我尝试了这样的事情,我得到了一个未定义的符号链接错误,就像你使用非const函数一样。但是,如果您从未采用其地址或道德等价物,那么您可能会在没有定义存储位置的情况下离开。我并没有对你是否应该*做出价值判断,而是在通用平台上看起来可以。 – 2014-10-04 07:17:47

1

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

为非静态成员提供初始值设定项的功能是新增功能(对于C++ 11)。它是一个完全不同的功能,即使它在语法级别上看起来很相似。这些初始化器被用作那些未被用户明确初始化的类成员的构建时初始化器。

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