構造関数が呼び出されるタイミング

7272 ワード

構造関数が呼び出されるタイミング
構造関数は、下の3つの場合に呼び出されます.
  • 対象ライフサイクルが終了し、破棄された場合.
  • deleteをアクティブに呼び出す.
  • オブジェクトiはオブジェクトoのメンバーであり、oの構造関数が呼び出されると、オブジェクトiの構造関数も呼び出される.

  • 第一のケース
    #include 
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    void main()
    {
        A a;
    }

    実行結果:
    constructing A
    destructing A

    2つ目のケース
    newのオブジェクトであれば、役割ドメインを離れても常に存在するため、プロアクティブdeleteが必要です.そうしないと、プログラムが終了したときにのみプロファイルが実行されます.ここではメモリの漏洩について説明します.例を挙げます.
    #include 
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    void fun() 
    {
        A *a = new A();
    }
    
    int main() 
    {
        while (1) 
        {
            fun();
        }
        return 0;
    }

    funを離れると、役割ドメインを離れますが、newで動的に空間を開くオブジェクトは解析されません.タスクマネージャを観察して、メモリが上昇しているのを見ることができます.しかし、あなたは他の場所でaが開いた空間を使用することはできません.aというポインタはスタックに保存されているので、役割ドメインを離れた後に自動的にプロファイル化されます(あるいは自動的に消えてしまいます)、しかし、その割り当て空間はスタックに割り当てられています.アクティブなプロファイルまたはプログラムが終了してこそ、空間を解放することができます.つまり、この空間のアドレスを失って、この空間を操作することはできません.
    3つ目のケース
    #include 
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    class C
    {
    public:
        C()
        {
            cout << "constructing C" << endl;
        }
        ~C()
        {
            cout << "destructing C" << endl;
        }
    private:
        int c;
    };
    
    class B : public A
    {
    public:
        B()
        {
            cout << "constructing B" << endl;
        }
        ~B()
        {
            cout << "destructing B" << endl;
        }
    private:
        int b;
        C c;
    };
    
    void main()
    {
        B b;
    }

    実行結果:
    constructing A
    constructing C
    constructing B
    destructing B
    destructing C
    destructing A

    Bの構造関数呼び出しの後、Bのメンバcの構造関数が呼び出される.
    上のコードのmain()関数の内容を
     A* a = new B;
    
     delete a;

    これはclass Bを呼び出す構造関数が呼び出されないため、class Cの構造関数も呼び出されないことを知っています.
    実行結果:
    constructing A
    constructing C
    constructing B
    destructing A

    class Aの構造関数を虚関数として宣言すると、class Bの構造関数も呼び出されます.たとえば、次のようになります.
    #include 
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        virtual ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    class C
    {
    public:
        C()
        {
            cout << "constructing C" << endl;
        }
        ~C()
        {
            cout << "destructing C" << endl;
        }
    private:
        int c;
    };
    
    class B : public A
    {
    public:
        B()
        {
            cout << "constructing B" << endl;
        }
        ~B()
        {
            cout << "destructing B" << endl;
        }
    private:
        int b;
        C c;
    };
    
    void main()
    {
        A* a = new B;
    
        delete a;
    }

    実行結果:
    constructing A
    constructing C
    constructing B
    destructing B
    destructing C
    destructing A

    この記事では、次の項目を参照してください.https://blog.csdn.net/weizhee/article/details/562833