下面代码的输出是什么?
class A { public: A() { } ~A() { cout<<"~A"<<endl; } }; class B:public A { public: B(A &a):_a(a) { } ~B() { cout<<"~B"<<endl; } private: A _a; }; int main(void) { A a; //很简单,定义a的时候调用了一次构造函数 B b(a); }
#include <iostream> using namespace std; class A { public: A() { cout << "Create A!" << endl; } A(const A& para) { cout << "Copy constructor A!" << endl; } ~A() { cout<<"~A"<<endl; } }; class B:public A { public: B(A &a):_a(a) { cout << "Create B!" << endl; } ~B() { cout<<"~B"<<endl; } private: A _a; }; int main(void) { A a; //很简单,定义a的时候调用了一次构造函数 B b(a); }
Create A! Create A! Copy constructor A! Create B! ~B ~A ~A ~A
class A { public: A() { cout<<"A"<<endl; } ~A() { cout<<"~A"<<endl; } }; class B:public A { public: B(A &a):_a(a) { cout<<"B"<<endl; } ~B() { cout<<"~B"<<endl; } private: A _a; }; void main(void) { A a; B b(a); }
A A B ~B ~A ~A ~A
加上拷贝构造函数---------------------------------------------------------------------- class A { public: A(){ cout<<"A"<<endl; } A(const A& other){ cout<<"copy A"<<endl;} ~A() { cout<<"~A"<<endl; } }; class B:public A { public: B(A &a):_a(a) { cout<<"B"<<endl; } ~B() { cout<<"~B"<<endl; } private: A _a; }; void main(void) { A a; B b(a); }
结果显示 A A copy A B ~B ~A ~A ~A
修改后----------------------------------------------------------------------------------class A { public: A() { cout<<"A"<<endl; } A(const A& other){ cout<<"copy A"<<endl;} ~A() { cout<<"~A"<<endl; } }; class B:public A { public: B(A &a) { cout<<"B"<<endl; } ~B() { cout<<"~B"<<endl; } private: A _a; }; void main(void) { A a; B b(a); }
结果为 A A A B ~B ~A ~A ~A
构造函数执行顺序:基类成员初始化列表->基类构造函数体->派生类成员初始化列表->派生类构造函数体
析构函数执行顺序:派生类析构函数->派生类成员变量->基类析构函数->基类成员变量
构造的顺序与析构相反,注意成员初始化列表一定在函数体内的代码之前执行,执行顺序为成员变量在类中声明的顺序,和成员初始化列表中的顺序无关:
class Base { public: Base(int a, int b) : _b(b), _a(a) { cout << "Base\n"; } private: int _a; int _b; };
执行顺序:
先是成员初始化列表:初始化_a
,初始化_b
,
然后是函数体:若有virtual函数,则先初始化vptr,然后执行用户代码cout << "Base\n";
main函数中,变量的释放顺序与定义的顺序相反,因此本题先析构b,再析构a
最终顺序为:
b
:B的析构函数->A的析构函数(B中数据成员_a
)->A的析构函数(子对象) a
:A的析构函数(main中的a)