定义静态成员在C++

问题描述:

我想这样定义一个公共静态变量:定义静态成员在C++

public : 
     static int j=0;  //or any other value too 

我正在就这一行编译错误:ISO C++禁止在类非const静态初始化成员'j'。

  1. 为什么在C++中不允许?

  2. 为什么const成员被允许初始化?

  3. 这是否意味着C++中的静态变量不会像在C中一样使用0进行初始化?

谢谢!

(1.)为什么在C++中不允许?

Bjarne Stroustrup's C++ Style and Technique FAQA class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

(2)为什么const的成员获准 初始化?

[dirkgently said it better]

(3)这是否意味着静态变量 在C++中没有初始化为0与C ?

据我所知,只要你在一个.cpp声明静态成员VAR这将是,如果你没有另行指定零初始化:

// in some .cpp 
int Test::j; // j = int(); 
+0

非常感谢您的回答,您可以阻止我将我的头脑听到! 虽然我有一个问题,有没有任何可能的方式来提供一个空指针,而定义参考成员? – 2014-02-20 22:59:18

+1

@TimVisee不知道是否有可能 - 至少以便携式,非UB方式 - 但你最终会得到一个无效的参考。如果你想要NULL语义只是使用一个指针或者可能使用诸如Boost Optional之类的东西。 – 2014-02-22 04:39:48

您必须在.cpp文件中初始化静态变量,而不是在类声明中初始化。

当您在类中声明一个静态变量时,它可以在不实例化类的情况下使用。

//Header file 
class Test 
{ 
    public: 
    static int j; 
}; 

//In cpp file 

//Initialize static variables here. 
int Test::j = 0; 

//Constructor 
Test::Test(void) 
{ 
    //Class initialize code 
} 

为什么不是在C++允许吗?

直到和除非你定义它,变量不会变成l值。

为什么const成员被允许初始化?

即使在这种情况下,如果您要获取变量的地址,则需要定义。

9.4.2静态数据成员

静态数据的声明 构件在其类定义是不 一个定义,并且可以比 CV以外的 不完全型的合格的虚空。一个静态数据成员的定义应该出现在一个包含成员的 类定义的名字空间范围内的 。在 名称空间范围的定义中,使用:: 运算符,静态数据成员的名称应按其类名合格 。在静态数据 成员的定义的初始化表达式 是同级车

同样的范围,这主要是一个使用神器,让你可以写:

class S { 
     static const int size = 42; 
     float array[ size ]; 
}; 

不这意味着C++中的静态变量不会使用0初始化为C中的 ?

不,他们是:

非本地变量

变量与静态存储时间 (3.7.1)或线程存储时限 (3.7

3.6.2初始化。 2)应在初始化之前进行初始化(8.5) ,然后进行 之前的位置。

尽管事情在C++ 0x中变得更复杂一些。现在可以初始化所有字面类型(与当前标准中只有整型相对),这意味着所有标量类型(包含浮点数)和某些类类型现在可以在声明中使用初始化程序进行初始化。

+0

为什么不需要定义静态常量整数?它(在.h中定义的static-const-int)编译,链接成功,没有定义。 如果是这样,因为当C++允许这种类型的声明没有定义,因为C++ 98?自C++ 03以来?真实的来源请。 C++ Standard(9.4.2)与编译器不同步。它提到,如果在计划中使用该成员,该成员仍将被定义。所以,我会告诉你,我不想从C++标准中引用。更好的是,GCC changelog/C++委员会注释。 – smRaj 2014-09-20 15:50:04

简短的回答:

这相当于说extern int Test_j = 0;

如果确实编译,会发生什么?每个包含你类的头文件的源文件都会定义一个称为Test :: j的符号,初始化为0.链接器往往不喜欢这样。

+4

+1。“extern”揭示了这个问题的性质。 – Cheezmeister 2013-05-12 22:13:06

class GetData   
{  
private:  
static int integer; //Static variable must be defined with the extension of keyword static;  
public:  
static void enter(int x)  
{  
integer = x; //static variable passed through the static function  
} 
static int show() //declared and defined 
{ 
    return integer; //will return the integer's value 
}   
};   
int GetData::integer = 0; //Definition of the static variable  
int main()  
{  
    GetData::enter(234); //value has been passed through the static function enter. Note that class containing static variables may not have the object in main. They can be called by scope resolution operator in main. 
    cout<<GetData::show();  
}