现在的位置: 首页 > 综合 > 正文

了解C++11(六)—— 初始化成员变量

2014年09月02日 ⁄ 综合 ⁄ 共 1358字 ⁄ 字号 评论关闭

在c++11以前,标准只允许常量的静态成员变量并且只能是整形或枚举型才能“就地(in-class)”初始化。并且static数据成员必须在类定义的外部进行定义。

class A
{
private:
    static const int period = 30;
    double daily_tbl[period]; // ok: period is constant expression
};

// definition of static member with no initializer;
// the initial value is specified inside the class definition
const int A::period;

对于非const的static数据成员,则不能在类的定义体中初始化,而是在类定义体的外部定义时进行初始化。

class B
{
private:
    static int count;
};

int B::count = 100;

在c++11中,标准对于成员变量的in-class初始化就宽松多了。c++11允许非静态成员变量进行in-class初始化。

class C
{
private:
    int i = 1;
    double d { 1.2 };
};

c++11支持使用等号(=)和花括号({})两种方式进行非静态成员变量的in-class初始化。

c++11同样支持以前的构造函数初始化列表,或者在构造函数的函数体中对变量进行初始化。

class D
{
public:
    D() : i(2) { i = 3; }
    void print() { cout << "i = " << i << endl; }
private:
    int i = 1;
};

int main()
{
    D d;
    d.print();

    return 0;
}

程序的输出结果是:“i = 3”。如果把构造函数中的赋值语句“i = 3”去掉,则程序的输出结果是是:“i = 2”。如果把初始化列表中的“i(2)”也去掉,则程序的输出结果是:“i = 1”。

所以,可以这么理解。程序先执行in-class初始化,然后是构造函数的初始化列表,最后是构造函数的函数体。

那这种in-class初始化有什么好处呢?在c++11之前,如果一个类有很多成员变量,那我们可能需要编写很多个构造函数,分别对应不同的初始化方式。在以前,可以通过调用公共的初始化函数来达到这个目的,那现在就可以使用in-class初始化的方式了,这种方式书写更简单,且效率也更高。

class E
{
    E() {}                                              	//不需要初始化i, d, s
    E(int a) : i(a) {}                                  	//不需要初始化d, s
    E(double b) : d(b) {}                              		//不需要初始化i, s
    E(string c) : s(c) {}                              		//不需要初始化i, d,
    E(int a, double b) : i(a), d(b) {}                  	//不需要初始化s
    E(int a, string c) : i(a), s(c) {}                  	//不需要初始化d
    E(double b, string c) : d(b), s(c) {}               	//不需要初始化i
    E(int a, double b, string c) : i(a), d(b), s(c) {}
private:
    int i = 100;
    double d = 1.2;
    string s = "in-class initialization. ";
};

最后,对于非常量的静态成员变量,c++11和c++98保持一致:还需要到头文件以外去定义它。

学习资料: 《深入理解c++11》

抱歉!评论已关闭.