zoukankan      html  css  js  c++  java
  • [C++]搞清楚类中构造与析构的顺序

    定义一个类对象时,首先根据初始化列表初始化类的成员(就算没有显式定义初始化列表,编译器也会默认地初始化一次),然后运行构造函数。因此,类成员的构造函数必定先于类的构造函数运行。

    class A
    {
    public:
        A()
        {
           puts("In A");
        }
        ~A()
        {
           puts("Out A");
        }
    };
    
    class B
    {
    public:
        B()
        {
           puts("In B");
        }
        ~B()
        {
           puts("Out B");
        }
    };
    
    class D
    {
    public:
        D()
        {
           puts("In D");
        }
        ~D()
        {
           puts("Out D");
        }
    };
    
    class X
    {
    public:
        X()
        {
           puts("In X");
        }
        virtual ~X()
        {
           puts("Out X");
        }
        virtual void test()
        {
           puts("test in X");
        }
        D d;
    };
    
    class C:public X
    {
    public:
        C()/*: b(), a()*/
        {
           puts("In C");
    
        }
        ~C()
        {
           puts("Out C");
        }
        virtual void test()
        {
           puts("test in C");
        }
    private:
        A a;
        B b;
    };
    
    int main()
    {
        X* p = new C;
        p->test();
        delete p;
    
        return 0;
    }

    new C的时候,由于C由X继承而来,因此先构造X。首先,按照初始化列表初始化X的成员变量,这里没有初始化列表,系统也会默认地为d进行默认初始化,此时调用D的构造函数,打印In D。(先初始化成员,再运行构造函数

    X的初始化阶段结束后,运行X的构造函数,打印In X。

    X部分构造结束后,开始构造C的部分。同样的先进行初始化工作,无论有无初始化列表,无论初始化列表的顺序如何,成员的初始化顺序都按声明顺序进行初始化。打印In A,In B。

    C的成员完成初始化后,调用C的构造函数,打印In C。

    /*----------------------------------至此,new C的过程完毕-----------------------------------------*/

    基类指针调用虚函数,进行动态绑定,输出test in C

    /*----------------------------------开始对指针p析构-----------------------------------------*/

    析构的顺序就是构造顺序的逆序。就是先析构父类,再析构子类。先析构本类,再析构本类的成员。

    于是打印的顺序为O C, O B, O A, O X, O D

    这个例子同时也解释了,为什么基类的析构函数要声明为虚函数。如果

    //不是虚函数 
     ~X()
     {
        puts("Out X");
     }

    那么delete p时候会直接析构p的静态类型X,所以C的成员以及C的析构函数将不会运行,这样就会造成内存泄露。

  • 相关阅读:
    java学习 接口与继承11 默认方法
    java学习 接口与继承10 内部类
    java学习 接口与继承9 抽象类
    java学习 接口与继承8 final
    理解管理信息系统
    vue中的错误日志
    vue中的ref属性
    2.有24颗外观完全一样的小球,其中有一个是空心的,现在只有一个天平,最少称几次能找出这个特殊的球?
    1.有888瓶编了号码的水及10只健康的小白鼠,其中一瓶水有毒,小白鼠饮用毒水一天后会死,最少需要几天可以找到哪瓶水有毒?
    SQL题1两表联查
  • 原文地址:https://www.cnblogs.com/iyjhabc/p/3308921.html
Copyright © 2011-2022 走看看