打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
关于类继承的构造与析构调用分析

  总体结论:派生类的构造函数在创建对象时调用,调用顺序如下:

       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;}/*运行结果 :ABC~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;}/*运行结果 :ABC~ 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;}/*运行结果 :ABC~ 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;}/*运行结果 :ABC~ C~ B~ A*/    

  原因分析:

      1.当父类析构函数不是虚函数时,进行编译时调用,只调用自身的析构函数。

      2.当父类析构函数是虚函数时,进行运行时调用,无论指针指的那个对象,系统都会调用相关类的析构函数。

       程序中最好把父类的析构函数声明虚函数,这样所有子类的析构函数也为虚函数,也为了防止内存泄露。

来源:http://www.icode9.com/content-4-37801.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C++中类的构造函数调用顺序
C++构造函数的调用顺序
C++多重继承
子类对象如何访问父类的成员变量?
C++类成员的初始化
C 学习笔记——继承和组合
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服