C++的初始化列表:
在C++中,有的构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表。初始化列表以一个冒号开始,紧接着就是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
class A
{
private:
int i;
double j;
public:
A():i(5),j(5.0){}
A()
{
i=5;
j=5.0;
}
};
上述两个构造函数的功能是一样的,一个可以由另一个代替,当然是不能同时出现的,这里只是举一个例子。
何时使用初始化列表:
- 常量成员
- 引用类型
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 为引用类型。
- 没有默认构造函数的类类型
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 初始化列表并不能指定初始化的顺序,正确的顺序是,首先初始化基类,其次根据派生类成员声明次序依次初始化。