c++构造函数之成员初始化队列member initialization list

发布时间 2023-05-06 15:47:27作者: 小小灰迪

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;      
}