C++构造函数处理顺序如下:
1、为传入的非引用实参通过拷贝构造函数建立临时变量,引用实参省略这一步。
2、调用基类构造函数。
3、处理成员变量的初始化工作,按照成员变量定义的顺序进行初始化。初始化列表里的变量使用拷贝构造函数进行初始化,否则使用默认构造函数进行初始化。
4、执行构造函数用户定义初始化内容
先看一段代码
#include <iostream>
using namespace std;
class M{
public:
M(){cout << "M default" << endl;}
~M(){cout << "~M" << endl;}
};
class T{
public:
T(){cout << "T default" << endl;}
~T(){cout << "~T" << endl;}
T(T &t) {cout << "T copy: " << endl;}
T& operator = (T &t){cout << "T assin: "<< endl;return *this;}
};
class A
{
public:
A() { data=666;cout << "A default: " << ++i << "\r" << endl; }
A(A &a) {data = a.data;cout << "A copy: " << ++i << endl;}
A& operator = (A &a){data = a.data;cout << "A assin: " << ++i << endl;return *this;}
~A() { cout<<"~A"<<endl; }
int data;
static int i;
};
int A::i = 0;
class B:public A
{
public:
B(){ cout << "B default" << endl;}
B(T &t)
{
t = t;
cout << "B:here" << endl;
}
~B()
{
cout<<"~B"<<endl;
}
private:
M _m;
T _t;
};
int main(void)
{
T t;
B b(t);
}
运行结果与解释如下:
T default ——T t执行T的默认构造函数
A default: 1 ——B(T &t)先执行基类默认构造函数
M default ——B(T &t)初始化成员变量_m,通过M的默认构造函数进行初始化
T default ——B(T &t)初始化成员变量_t,通过T的默认构造函数进行初始化
T assin: ——B(T &t)执行_t=t这句复制语句,调用T的赋值构造函数
B:here ——B(T &T)执行cout语句,打印消息
~B ——析构函数,与构造函数执行顺序相反
~T ——析构函数,与构造函数执行顺序相反
~M ——析构函数,与构造函数执行顺序相反
~A ——析构函数,与构造函数执行顺序相反
~T ——析构函数,与构造函数执行顺序相反
注意:赋值构造函数是额外加的操作,没有析构函数与其对应。
如果将B(T &t)改成B(T t),则会得到如下结果
T default
T copy: ——执行本文开篇的第一步,使用拷贝构造函数初始化临时变量
A default: 1
M default
T default
T assin:
B:here
~T ——构造函数执行完毕,临时变量生命周期结束,执行析构函数
~B
~T
~M
~A
~T
如果将_t加入到初始化列表中则会使用拷贝构造函数进行初始化。
B(T t) :_t(t)
{
cout << "B:here" << endl;
}
得到结果如下
T default
T copy:
A default: 1
M default
T copy: ——初始化列表里的函数使用拷贝构造函数进行初始化
B:here
~T
~B
~T
~M
~A
~T