2011-06-29 17 views
11
class D: A 
{ 
    B obj; 
    C obj2; 
} 

ここで、どのような構成が保証されますかクラス構成要素の初期化順序

私はDはA、BおよびCの後に構築されることを知っている、しかし、私が本当に知りたいのは、AがBまたはCの前に構築することがを保証されているかどうか、またはBがする保証されているかどうかさえありますC.

前に構築され、私はあなたが明示的な初期化子リストを持つことができます知っている:

D(): A(), B(), C() 
{} 

が、その初期化子リストは、初期化のを決定するのですか?

また、いずれかのコンポーネントにデフォルトのコンストラクタがあるかどうかは関係ありませんか?

+1

私に叫ぶのをやめてください! –

答えて

10

C++ 03標準ISO/IEC 14882:2003(E)§12.6.2/ 5 [class.base。INIT]:

初期化は次の順序で進行しなければならない。
- まず、そして唯一の最も派生クラスのコンストラクタのために、以下に説明、仮想基底クラスは、彼らが深さに表示される順序で初期化されなければならないとして、基本クラスの有向非循環グラフの左から右への横断。ここで、「左から右」は派生クラスの基本クラス名の出現順である基本指定子リスト
- 直接基底クラスは、基本指定子リストに表示されるように(mem-initializersの順番にかかわらず)、宣言順に初期化されます。
- 非静的データメンバは、クラス定義で宣言された順番で初期化されます(mem-initializersの順番に関係なく)。
- 最後に、コンストラクタの本体が実行されます。
[注:初期化の逆の順序でベースサブオブジェクトとメンバサブオブジェクトが確実に破棄されるようにするには、宣言順序が必須です。 ]

したがって、この場合には、あなたがして、初期化の順序は、最初の基底クラスA、(それはクラス定義でクラスメンバーのリストの最初に表示されますので)その後、サブオブジェクトBになることが保証されていますサブオブジェクトC。初期化子リストの順序は、メンバーがデフォルトのコンストラクタを持っているか持っていないかどうかとは無関係です。メンバーがデフォルトのコンストラクタを持たず、初期化子リストで明示的に初期化されていない場合、不特定の値。

9

ただし、初期化リストで初期化の順序を決定していますか?

いいえ。初期化リストは、は、メンバーデータと基本サブオブジェクトの初期化の順序を決定しません。彼らの言及のために、メンバーはその宣言の順序で初期化され、ベースサブオブジェクトが構築されている - 左から右へ:

struct A : B, C {} //B is constructed before C 

はまた、ベースサブオブジェクトは、メンバーデータの初期化前に構築されています。上記の構造体の初期化の

struct A : B, C 
{ 
     D d; 
     E e; 
}; 

注文:

B  => C  => d => e 
subobject subobject  member member 

そして、彼らは逆の順序で破壊しています。

+0

は明示する必要があります。初期化の順序を制御する宣言の順序です。 –

+0

クールです。基本クラスとメンバーオブジェクトはどうですか?初期化されることは保証されていますか?私は技術的に基本クラスはメンバーの前に宣言されていると思います。 :) – matt

+0

@matt:今答えを見てください。 – Nawaz

1

おそらく、壊れたコードのこの例では、説明するのに役立ちます:

を、私はそうのようなクラスを定義する場合:

class Connection { 

    boost::asio::tcp::ip::socket _socket; 
    boost::asio::io_service _io_service; 

    Connection() : _io_service(), _socket(_io_service) 
    { 
    } 
}; 

これは、すべての現代のコンパイラで失敗します。 _socketは最初にクラスメンバーとして定義されているため、初期化リストはコンパイラに対して_io_serviceを最初に初期化するように要求しても、最初に初期化リストを初期化しようとします。しかし、はまだ初期化されていないため(ソケットコンストラクタは初期化された_io_serviceに依存します)、_socketの初期化によってsegfaultが発生します。

おそらく誰かがこの動作を指示する標準の適切なセクションを引用することができます。

質問の後半では、基本クラスは常にクラスがメンバーを所有する前に初期化されます。

+0

「現代コンパイラ」とはどういう意味ですか?私は少なくともTC3.0以降、C++で作業していますが、初期化順序が間違っているコンパイラを思い出すことができません。 – sbi

関連する問題