面接集錦--コンストラクション関数の初期化順序の問題


クラスコンストラクタの初期化順序は、C++からVisual C++に管理されます.
コンストラクション関数の初期化順序の比較
C++管理拡張では、コンストラクション関数の初期化は次の順序で行われます.
  • ベースクラスのコンストラクション関数が存在する場合、コンストラクション関数が呼び出されます.
  • は、クラスの初期化リストを計算する.
  • クラス構築関数のコード本文を実行します.

  • この実行手順は、本機C++プログラミングと同じ規則を遵守します.新しいVisual C++言語はCLRクラスの実行順序を規定しており、以下の通りである.
  • は、クラスの初期化リストを計算する.
  • ベースクラスのコンストラクション関数が存在する場合、コンストラクション関数が呼び出されます.
  • クラス構築関数のコード本文を実行します.上記の文字はコードで表される:
    __gc class A
    {
    public:
       A() : _n(1)
       {
       }
    
    protected:
       int _n;
    };
    
    __gc class B : public A
    {
    public:
       B() : _m(_n)
       {
       }
    private:
       int _m;
    };
                  ,     B     ,            :
    1.     A      。   _n        1。 
    
    2.    B       。   _m        1。 
    
    3.    B      。
             Visual C++          :
     ref class A
    {
    public:
       A() : _n(1)
       {
       }
    
    protected:
       int _n;
    };
    
    ref class B : A
    {
    public:
       B() : _m(_n)
       {
       }
    private:
       int _m;
    };
               B            :
    1.    B       。   _m        0(0   _m          )。 
    
    2.     A      。   _n        1。 
    
    3.    B      。
    
        ,        ,             。   B            A          。        A      。                           ,              。 
    
    さらに詳細な構造順序は以下の通りである:C++コンストラクタは以下の順序で呼び出される:(1)任意の仮想ベースクラスのコンストラクタはそれらが継承された順序で構築される;(2)任意の非仮想ベースクラスの構築関数は、それらが継承された順序で構築される.(3)任意のメンバーオブジェクトの構造関数は、それらが宣言した順序で呼び出される.(4)クラス独自のコンストラクション関数.
    #include <iostream>
    
    using namespace std;
    
    class OBJ1
    {
    public:
        OBJ1(){ cout <<"OBJ1
    "; } }; class OBJ2 { public: OBJ2(){ cout <<"OBJ2
    "; } }; class Base1 { public: Base1(){ cout <<"Base1
    "; } }; class Base2 { public: Base2(){ cout <<"Base2
    "; } }; class Base3 { public: Base3(){ cout <<"Base3
    "; } }; class Base4 { public: Base4(){ cout <<"Base4
    "; } }; class Derived :public Base1, virtual public Base2, public Base3, virtual public Base4 { public: Derived() :Base4(), Base3(), Base2(), Base1(), obj2(), obj1() { cout <<"Derived ok.
    "; } protected: OBJ1 obj1; OBJ2 obj2; }; int main() { Derived aa; cout <<"This is ok.
    "; int i; cin >> i; return 0; } : Base2 Base4 Base1 Base3 OBJ1 OBJ2 Derived ok. This is ok.
    の を すると、 されたベースクラスの で ベースクラスが も が く、 いで のベースクラスであり、 いで クラスのメンバー が されるという が られる. クラスのメンバーは、すべてのダミーベースクラスで された で されます. に、すべての ベースクラスで された で クラスのメンバーを します.