初始化列表 知多少

C++的初始化列表:

在C++中,有的构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表。初始化列表以一个冒号开始,紧接着就是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。

class A
{
private:
    int i;
    double j;
public:
    A():i(5),j(5.0){}
    A()
    {
        i=5;
        j=5.0;
    }
};

上述两个构造函数的功能是一样的,一个可以由另一个代替,当然是不能同时出现的,这里只是举一个例子。

何时使用初始化列表:

  1. 常量成员
  2. 引用类型
class A
{
private:
	int x,℞
	const double pi;
public:
	A(int i):x(i),rx(x),pi(3.14)
	{}
	void display()
	{cout<<"x="<<x<<"rx="<<rx<<"pi="<<pi<<endl;}
};

上面的代码中,pi 为常量, rx 为引用类型。

  1. 没有默认构造函数的类类型
class Test1
{
public:
    Test1(int a):i(a){}
    int i;
};
class Test2
{
public:
    Test1 test1 ;
    Test2(Test1 &t1){test1 = t1 ;}
};

因为Test1 没有默认的构造函数,上述代码会出现报错。

应该必须用初始化列表,正确的代码如下:

class Test1
{
public:
    Test1(int a):i(a){}
    int i;
};
class Test2
{
public:
    Test1 test1 ;
    Test2(int x):test1(x){}
};

如果没有定义任何构造函数 ,C++编译器会自动创建一个默认构造函数 。 如果已经定义了一个构造函数,编译器不会自动创建默认构造函数,只能显式调用该构造函数。

初始化顺序:

按照数据成员在类中的声明顺序进行初始化,与初始化成员列表中出现的顺序无关

class Test
{
private:
    int i,j;
public:
    Test(int x):j(x),i(j){}//i的值未定义
};

上述代码中,在定义的时候,i 比 j 提前定义,所以也应该提前初始化。

下面的才是正确的:

{
private:
    int i,j;
public:
    List(int x):i(x),j(i){};
};

总结一下初始化列表:

1 因为初始化列表中无法直接初始化基类的数据成员,所以你需要在列表中指定基类的构造函数,如果不指定,编译器则会调用基类的默认构造函数。

2 推荐使用初始化列表,它会比在函数体内初始化派生类成员更快,因为在分配内存后,在函数体内又多进行了一次赋值操作。

3 初始化列表并不能指定初始化的顺序,正确的顺序是,首先初始化基类,其次根据派生类成员声明次序依次初始化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章