2011-11-25 96 views
12

在C和C++中,所有静态变量默认初始化为零。为什么要在C++中初始化静态类变量?

这不是静态类数据成员的情况。这是为什么?

#include <iostream> 
using namespace std; 

int var; 

class MyClass 
{ 
public: 
    static int classVar; 
}; 
int MyClass::classVar = 0; // Why I have to init it here? 

int main(void) 
{ 
    cout << ::var << endl;   // this is initalized to ZERO by default 
    static int var; 
    cout << var << endl;   // and this also is initalized to Zero 
    cout << MyClass::classVar << endl; 

    return 0; 
} 
+0

您不确定** var **是否已初始化为0.可能,有时很可能,但不确定。 –

+3

@AlessandroPezzato:实际上,在执行动态初始化之前,标准显式地为所有全局变量清零内存......除了受字面值影响的内置函数,我认为可以直接影响(在因为它是不可观测的。 –

回答

21

类范围,

int MyClass::classVar = 0; // Why I have to init it here? 

定义

static int classVar; 

声明,即。承诺该变量将被定义为某处:您必须定义恰好一次您声明的变量。

基本原理是类声明可能会包含在多个源文件中。它的一部分是一个定义,它会发生倍增:这是错误的(例外是内联[成员]函数)。

注意的是,根据值初始化规则,你可以用

int MyClass::classVar; // Zero-initialized ! 

的定义相处。

在命名空间内声明的变量定义太(除非他们是extern合格):

int var; 

是一个声明,以及一个定义:如果你把它放到头并将其包含在多个翻译单位,你有一个错误(“乘法定义的符号”,或沿着这些线)。

[注意,在C++(而不是在C)中,如果上述varconst,它自动成为static并且没有扰定义规则违反应该它被放入一个乘法包含的头。这又稍微偏离主题,但随时问细节]认为

+2

我不确定那是什么被问到。我将其解读为“为什么我必须把'= 0;'在那里?” – Mat

+0

@Alexandre C .:如果你也解释了为什么需要,这将是一件好事。 – Nawaz

+3

因此,如果你只需要零初始化,'int MyClass :: classVar;'应该已经足够了。从来没有尝试过,但根据标准和删除的答案,它实际上。 – zerm

2

您必须初始化您的静态类数据变量,因为您必须告诉编译器它们的值是什么。类不需要具有默认值的概念。

变量类型具有逻辑“零值”,对于int它是0,对于double 0.0,对于string“”等。相反,类不一定具有默认值。考虑一下,例如class Rectangle。它的零点值是多少? - 一个长方形的零方形或长方形的单位边长?对于静态变量,编译器会要求您自己定义静态变量必须具有的值,因为不是每个数据类型都可以通过默认值进行初始化。

+1

我认为你在这里弄错了:没有什么能够阻止你定义一个静态变量而不是初始化它,如果这个变量是一个类的实例,那么它的构造函数将被调用 – qdii

+0

静态变量必须被定义,构造函数不会初始化它。考虑下面的例子...如果“int test :: k;”将被评论,它将不会编译。 class test { public: static int k; }; int test :: k; int main() { test t; cout << t.k; return 0; } – rakesh

+0

@victor是的,你是对的,谢谢你注意到我。问题是关于定义一个静态变量,而不是它的初始化。 –