2017-01-01 6 views
0

例1:コンストラクタ呼び出しシーケンス

#include <iostream> 

class A 
{ 
public: 
    A(int a) 
    { 
     std::cout << "A: " << a << '\n'; 
    } 

     A() 
    { 
     std::cout << "A" <<'\n'; 
    } 
}; 

class B: public A 
{ 
    private: 
    int b; 
    A a1; 
public: 
    B(int a, double b) 
    : a1(a) 
    { 
     std::cout << "B: " << b << '\n'; 
    } 

}; 

class C: public B 
{ 
public: 
    C(int a , double b , char c) 
    : B(a, b) 
    { 
     std::cout << "C: " << c << '\n'; 
    } 
}; 

int main() 
{ 
    C c(5, 4.3, 'R'); 

    return 0; 
} 

出力:

A 
A: 5 
B: 4.3 
C: R 

例2:

#include <iostream> 

class A 
{ 
public: 
    A(int a) 
    { 
     std::cout << "A: " << a << '\n'; 
    } 

     A() 
    { 
     std::cout << "A: " <<'\n'; 
    } 
}; 

class B: public A 
{ 
    private: 
    int b; 
    A a1; 
public: 
    B(int a, double b) 
    : A(a) 
    { 
     std::cout << "B: " << b << '\n'; 
    } 

}; 

class C: public B 
{ 
public: 
    C(int a , double b , char c) 
    : B(a, b) 
    { 
     std::cout << "C: " << c << '\n'; 
    } 
}; 

int main() 
{ 
    C c(5, 4.3, 'R'); 

    return 0; 
} 

出力:

A: 5 
A: 
B: 4.3 
C: R 

Whを私はCPPから基本クラスのコンストラクタが最初に呼び出され、次にメンバが初期化され、最終的に派生クラスのコンストラクタが呼び出されることを理解しています。なぜ、出力の最初の2行が同じにならないのですか?

答えて

3

なぜあなたはそれらが同じであると思いますか?最初の例では、この断片:

B(int a, double b) 
: a1(a) 

それは最初の暗黙的に、その後、端末に単一Aを出力する基底クラスは、(デフォルトのコンストラクタを使用して)、A: 5を出力するメンバ変数a1を初期化する初期化します。あなたのコードはに実際に等価です:

第二の例では、正確に反転され
B(int a, double b) 
: A(), // implicit 
    b(), // implicit 
    a1(a) 

B(int a, double b) 
: A(a) 

あなたは明示的に単一の引数のコンストラクタ(出力A: 5)とベースを初期化し、その後、メンバ変数は、デフォルトで暗黙的に初期化されますコンストラクタ(出力A)。このコードは同等です:

B(int a, double b) 
: A(a), 
    b(), // implicit 
    a1() // implicit 

あなたが明示的に初期化コードコンストラクタ内かどうかを置くかどうかは関係ありません - ALL基底クラスが最初に初期化され、その後、ALLメンバ変数が初期化されています。これらの初期化は、指定した引数を使用するか、省略した場合はデフォルトで初期化されます。イニシャライザを省略し、デフォルトコンストラクタが使用できない場合、コンパイルは失敗し、エラーが発生します。

関連する問題