C++类中成员变量的初始化有两种方式:
构造函数初始化列表和构造函数体内赋值。
初始化列表对成员变量做的事情叫做初始化,而构造函数体内对成员变量做的事情就叫做赋值了。
整个构造函数的执行过程包括(初始化列表以及构造函数体内)都属于该对象初始化的过程
初始化早于赋值,它是随着对象的诞生一起进行的。而赋值是在对象诞生以后又给予它一个新的值。
因为初始化列表只调用一次拷贝构造函数。而构造函数内赋值调用一次默认的构造函数和赋值操作,效率明显就变差了。
c++在哪些情况下只能使用初始化列表而不能用赋值
1-如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数
2-需要初始化const修饰的类成员
3-需要初始化引用成员数据
4.类成员为没有默认构造函数的类类型
因为:常量不能被赋值,只能被初始化,所以必须在初始化列表中完成,C++引用也一定要初始化,所以必须在初始化列表中完成。
class CTestBase
{
public:
CTestBase(int a);
private:
int val;
std::shared_ptr<int> m_ptr;
};
class CTestconst {
public:
CTestconst(int a, int c, int *pd);
virtual ~CTestconst() {}
int m_a;
const int m_c;
const int *m_pd;
};
class CTestconstson :public CTestconst {
public:
CTestconstson(int a,int b, int c, int *pd);
virtual ~CTestconstson() {}
int m_b;
CTestBase base;
};
CTestBase::CTestBase(int a)
:val(a),
m_ptr(new int(2))
{
}
CTestconst::CTestconst(int a, int c, int *pd):
m_a(a),m_c(c),m_pd(pd)
{
}
CTestconstson::CTestconstson(int a, int b, int c, int *pd):
CTestconst(a,c,pd),m_b(b), base(a)
{
}
调用:
CTestBase ctestbase(1);
int pdson = 2;
CTestconstson(1, 1, 1, &pdson);
讲解:
1如果在初始化 CTestBase 构造函数时抛出异常,m_ptr 已经是一个被完全构造的
对象,所以它能被自动删除掉。
延伸:
1.如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数的原因
因为子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法。所以在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。
c++ 类与默认函数、包括构造函数和析构函数的特点_小飞侠hello的博客-CSDN博客
明显构造函数初始化列表的方式得到更高的效率。