初始化列表
class Baby{
public:
//初始化列表,以冒号开头,并用逗号隔开,括号内为初始值,不能缺少{}
Baby(string s,int a):name(s),age(a){};
private:
string name;
int age;
};
初始化只能进行一次,而构造函数体内可进行多次赋值。
class Baby{
public:
Baby(string s,int a):name(s),age(a)//这里才是初始化的地方
{
//这里就不是初始化,是构造函数体内赋值
name=s;
age=a;
};
private:
string name;
int age;
};
注意:
1、每个成员变量在初始化列表中只能出现一次
2、初始化类成员时,按照声明的顺序初始化
为什么使用初始化列表呢?
初始化类中成员的方式有两种:
1、使用初始化列表
2、在构造函数体内进行赋值操作
对于内置类型,如int,float等,上面两种方式差别不大,但是对于类类型,一般都会使用初始化列表,因为使用初始化列表可以少一次默认构造函数的调用,这对于类来说,非常高效。
只能用初始化列表的情况
1、常量成员。
即const成员变量。因为常量成员只能初始化不能进行赋值。
2、引用类型。
引用必须在定义的时候初始化,并且不能重新赋值,故也要写在初始化列表中。
3、没有默认构造函数的类类型。
因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。
//自定义类,没有默认构造函数
class B{
public:
B(int b):_b(b){};
private:
int _b;
};
class Baby{
public:
//一定要用初始化列表初始化
Baby(string s,int a,double w,int b):name(s),age(a),weight(w),b1(b){};
private:
string name;
int &age;//引用类型
const double weight;//常量成员
B b1;
};
补充:
构造函数的执行分为初始化阶段和计算阶段
初始化阶段
所有类类型的成员都会在初始化阶段初始化,即使该成员没有出现在构造函数的初始化列表中。
计算阶段
用于执行构造函数中的赋值操作。