2017-05-29 8 views
1

これは私のコードで、あなたはまた、子供のコンストラクタを呼び出す必要があるので、私はX(){}ラインを持っている必要がありhttp://cpp.sh/5lsds親クラスのコンストラクタは、プライベート変数に値を代入しません

#include "iostream" 
using namespace std; 
class X{ 
private: 
    int c; 
public: 
    X(){} 
    X(int b){ 
    c = 11; 
    } 
    int getC(); 
}; 
class Z:public X{ 
public: 
    Z(int n){ 
     X(23); 
    } 
}; 
int main() 
{ 
    Z z(1); 
    cout<<z.getC()<<endl; 
    return 0; 
} 
int X::getC(){ 
    return c; 
} 

からそれを実行することができます親のデフォルトコンストラクタ

http://cpp.sh/5lsdsからプログラムを実行すると、11と予想されますが、出力が0であることがわかります。 ZコンストラクタはXコンストラクタをintパラメータで呼び出し、cの値を11に設定しますが、出力は0に設定されています。

+2

'X(23);'は一時的なXを作成し、すぐに破棄することを意味します。これは '* this'のXサブ部分とは関係ありません –

+1

JavaのバックグラウンドからC++に来たのならば、それをすべて忘れてしまいます。 –

答えて

5

あなたはクラスのコンストラクタの定義ではmember initializer list

を使用する必要があり、メンバー初期化子リストは、直接および仮想ベースサブオブジェクトと非静的データメンバの初期化子を指定します。

Z(int n) : X(23) {} 

子コンストラクタは親のデフォルトコンストラクタを呼び出す必要があるので、私はX(){}ラインを持っている必要があります。

メンバの初期化リストを使用すると、このコードサンプルでは再度必要ありません。コンストラクタの体内でX(23);については

、あなただけのZのベースサブオブジェクトXとは何の関係も持た​​ない、一時的なXを作成しています。デフォルトのコンストラクタX(つまりX::X())が使用されます。すなわち、それはと同等です:

Z(int n) : X() { // initialize the base suboject X via X::X() 
    X(23);  // create an unnamed temporary via X::X(int) 
} 
4

あなたは

基底クラスのコンストラクタを呼び出さない
Z(int n){ 
    X(23); 
} 

これは無名の一時的なXオブジェクトを作成し、そのコンストラクタに23を渡します。これは、C++でZ.

のXサブオブジェクトを構築していない、我々はメンバー初期化子リストの構文を使用して拠点とメンバーを構築します:

X(int b) : 
    c(11) 
{} 

Z(int n) : 
    X(23) 
{} 

メンバー初期化子リストの構文はかなり相当です単純な整数が構築されたメンバであるときに行う代入。しかし、より複雑なサブオブジェクトが最初にデフォルトで構築され、割り当て演算子が呼び出されることに注意してください。これにより、パフォーマンスの大幅な(悪化する)相違が、メンバーイニシャライザリストに指定されて一度だけ作成されるようになる可能性があります。

関連する問題