c++构造函数之成员初始化队列member initialization list
1. member初始化最好在member initialization list
中初始化
因为会constructor可能会扩张代码,会产生临时的object对象,然后将它初始化后,以一个assignment运算符将临时对象指定给类member,然后再销毁临时对象
以下情况会导致效率比较低:
- 初始化一个reference member;
- 当初始化一个const member时;
- 当调用一个base class的constructor,而它拥有一组参数时;
- 当调用一个member class的constructor,而它拥有一组参数时;
demo
在构造函数里面test被构造了两次,在成员初始化队列中,只构造了一次。
#include <iostream>
using namespace std;
class test{
public:
test(){
cout << "构造函数"<<endl;
}
test(int i){
cout << "int i 构造函数"<<endl;
}
test(const test& rtest){
cout << "拷贝构造函数"<<endl;
}
~test(){
cout << "析构函数"<<endl;
}
};
class memInitList
{
private:
test data;
public:
memInitList(){
data = test(0); // 两次构造
}
};
class memInitList2{
private:
test data;
public:
memInitList2() : data(test(0))
{
}
};
int main(){
memInitList test;
cout<<"-----------"<<endl;
memInitList2 test2;
cout<<"+++end+++"<<endl;
}
构造函数
int i 构造函数
析构函数
-----------
int i 构造函数
+++end+++
析构函数
析构函数
2. 编译器将初始化队列的以声明顺序
安插在constructor中,而不是初始化队列的顺序
安插的位置为explict user code之前
3. 初始化使用存在constructor体内的一个member,而不是member initialization list中的member
调用类成员函数来初始化一个member
这种情况是在member initialization list
调用一个成员函数来初始化成员member,可能会出现未定义的行为。
X::X(int val) : i(xfoo(val)),j(val)
{}
在初始化队列中,子类调用子类成成员函数来初始化父类
class FooBar:public X{
int _fval;
public:
int fval(){return _fval;}
FooBar(int val): _fval(val), X(fval()){}
};
可能会被展开为:
// 伪代码
FooBar::FooBar()
{
X::X(this, this->fval()); // 未定义行为
_fval = val;
}