总体结论:派生类的构造函数在创建对象时调用,调用顺序如下:
1.调用虚基类的构造函数(若有多个虚基类,调用顺序为继承的顺序。);
2.调用基类的构造函数(若有多个基类,调用顺序为继承的顺序。);
3.调用类类型的成员对象的构造函数(调用顺序为定义的顺序);
4.调用自身的构造函数。
析构函数的调用顺序一般和构造函数的调用顺序相反,但分如下几种情况:
1.当父类的指针 new一个子类的临时对象时。若父类的析构不是虚函数,则delete的时候不调用子类的析构,只调用父类的析构;
若父类的析构是虚函数,则delete的时候先调用子类的析构,后调用父类的析构;
2.当子类的指针 new一个子类的临时对象时。不管父类的析构是否为虚函数,delete的时候都会先调用子类的析构,后调用父类的析构;
代码验证:
class A { public: A() { cout << " A" << endl; } ~A() { //不是虚函数 cout << "~ A" << endl; } }; class B { public: B() { cout << " B" << endl; } ~B() { //不是虚函数 cout << "~ B" << endl; } }; class C:public A,public B { public: C() { cout << " C" << endl; } ~C() { cout << "~ C" << endl; } }; int main() { A *a = new C(); delete a; return 0; } /*运行结果 : A B C ~A */
class A { public: A() { cout << " A" << endl; } virtual ~A() { //是虚函数 cout << "~ A" << endl; } }; class B { public: B() { cout << " B" << endl; } virtual ~B() { //是虚函数 cout << "~ B" << endl; } }; class C:public A,public B { public: C() { cout << " C" << endl; } ~C() { cout << "~ C" << endl; } }; int main() { A *a = new C(); delete a; return 0; } /*运行结果 : A B C ~ C ~ B ~ A */
class A { public: A() { cout << " A" << endl; } virtual ~A() { //是虚函数 cout << "~ A" << endl; } }; class B { public: B() { cout << " B" << endl; } virtual ~B() { //是虚函数 cout << "~ B" << endl; } }; class C:public A,public B { public: C() { cout << " C" << endl; } ~C() { cout << "~ C" << endl; } }; int main() { C *c = new C(); delete c; return 0; } /*运行结果 : A B C ~ C ~ B ~ A */
class A { public: A() { cout << " A" << endl; } ~A() { //不是虚函数 cout << "~ A" << endl; } }; class B { public: B() { cout << " B" << endl; } ~B() { //不是虚函数 cout << "~ B" << endl; } }; class C:public A,public B { public: C() { cout << " C" << endl; } ~C() { cout << "~ C" << endl; } }; int main() { C *c = new C(); delete c; return 0; } /*运行结果 : A B C ~ C ~ B ~ A */
原因分析:
1.当父类析构函数不是虚函数时,进行编译时调用,只调用自身的析构函数。
2.当父类析构函数是虚函数时,进行运行时调用,无论指针指的那个对象,系统都会调用相关类的析构函数。
程序中最好把父类的析构函数声明虚函数,这样所有子类的析构函数也为虚函数,也为了防止内存泄露。
原文地址:https://www.cnblogs.com/parzulpan/p/9744216.html
时间: 2024-11-10 11:50:41