22

派生クラスのコンストラクターで継承されたメンバーの初期化について質問があります。コード例:

class A
    {
public:
    int m_int;
    };

class B: public A
    {
public:
    B():m_int(0){}
    };

このコードは私に次の出力を与えます:

In constructor 'B::B()': Line 10: error: class 'B' does not have any field named 'm_int'

http://codepad.org/tn1weFFPを参照)

なぜこれが起こるのか推測していますか?m_intのメンバーである必要があり、 inの初期化が発生したときにB親クラスAがすでに初期化されている必要があります(親コンストラクターは継承されたクラスのメンバー初期化の前に実行されるため)。私の推論の間違いはどこにありますか?このコードで実際に何が起こっているのでしょうか?m_intB

EDIT:このメンバーを初期化する他の可能性(ベースコンストラクターまたは派生コンストラクターの割り当て)を知っていますが、それを試す方法でなぜ違法なのかを理解したいのですが?いくつかの特定のC++言語機能など?可能であれば、C++標準の段落を教えてください。

4

4 に答える 4

22

あなたはあなたが持っているのと同じようにm_intを初期化するAのコンストラクターを作る必要があります(それはBだけがそれを呼び出すことができるように保護することができます)そしてあなた:A(0)はあなたが持っているところを呼び出します:m_int(0)

m_int = 0Bのコンストラクターの本体に設定することもできます。(あなたが説明しているように)アクセス可能であり、特別なコンストラクター構文では利用できません。

于 2010-10-21T04:14:53.863 に答える
4

あなたが欲しいのはこれです:

class A{
public:
    A() : m_int(0);
    int m_int;
};

m_int正しい場所で初期化されます。

編集:

m_int上記のコメントから、で変数を初期化しようとしたときにコンパイラが文句を言う理由は、Bのコンストラクタによってすでに初期化されているためですA。つまり、何かを再初期化することはできず、再割り当てするだけです。したがって、上記のベンジャクソンのように再割り当てするか、適切な場所で初期化することができます。

于 2010-10-21T04:15:21.200 に答える
4

クラスのインスタンスを構築するには、B最初にクラスのインスタンスをインスタンス化しますA。そのインスタンス化中m_intに初期化されます。のコンストラクターが呼び出されるのはその初期化の後であるbため、を再初期化することはできませんm_int。それが目標である場合Aは、intを受け取るコンストラクターを実装し、Bの初期化リストでそれを呼び出すことができます。

class A
{
public:
  A(int x): m_int(x) {}
  int m_int;
};

class B: public A
{
public:
  B(): A(2) {}
};
于 2010-10-21T04:17:20.297 に答える
0

Aでコンストラクターを作成し、B()を使用します。A(2){} B():m_int(0){}の代わりに動作します。

于 2017-05-05T09:53:56.930 に答える