web-dev-qa-db-ja.com

派生クラスコンストラクターで基本クラスメンバー変数を初期化するにはどうすればよいですか?

なぜこれができないのですか?

class A
{
public:
    int a, b;
};

class B : public A
{
    B() : A(), a(0), b(0)
    {
    }

};
99
amrhassan

aのメンバーではないため、bBおよびBを初期化できません。これらはAのメンバーであるため、Aのみがそれらを初期化できます。それらを公開してからBで割り当てを行うことができますが、カプセル化が破壊されるため推奨されません。代わりに、A(またはBのサブクラス)を初期化できるように、Aにコンストラクターを作成します。

class A 
{
protected:
    A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
    // Change "protected" to "public" to allow others to instantiate A.
private:
    int a, b; // Keep these variables private in A
};

class B : public A 
{
public:
    B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
    {
    } 
};
115
In silico

privateabのメンバーであるため、それらはAであるという事実は別として、これらはAのコンストラクターによって初期化されることを意図しています。他のクラスのコンストラクター(派生または非派生)。

試してください:

class A
{
    int a, b;

protected: // or public:
    A(int a, int b): a(a), b(b) {}
};

class B : public A
{
    B() : A(0, 0) {}
};
24
NPE

どういうわけか、誰も最も簡単な方法をリストしませんでした:

class A
{
public:
    int a, b;
};

class B : public A
{
    B()
    {
        a = 0;
        b = 0;
    }

};

初期化子リストのベースメンバーにはアクセスできませんが、コンストラクター自体は、他のメンバーメソッドと同様に、ベースクラスのpublicおよびprotectedメンバーにアクセスできます。

3
Violet Giraffe
# include<stdio.h>
# include<iostream>
# include<conio.h>

using namespace std;

class Base{
    public:
        Base(int i, float f, double d): i(i), f(f), d(d)
        {
        }
    virtual void Show()=0;
    protected:
        int i;
        float f;
        double d;
};


class Derived: public Base{
    public:
        Derived(int i, float f, double d): Base( i, f, d)
        {
        }
        void Show()
        {
            cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
        }
};

int main(){
    Base * b = new Derived(10, 1.2, 3.89);
    b->Show();
    return 0;
}

これは、Derivedクラスオブジェクトに存在するBaseクラスデータメンバーを初期化し、Derivedクラスコンストラクター呼び出しを介してこれらの値をプッシュする場合の実用的な例です。

2

これはまれなケースでは便利ですが(そうでない場合は、言語で直接許可されます)、 Base from Member idiom を見てください。これはコードフリーのソリューションではありません。継承のレイヤーを追加する必要がありますが、仕事は完了します。定型コードを回避するには、 boostの実装 を使用できます

1

どうしてできないの?この言語では、派生クラスの初期化子リストで基本クラスのメンバーを初期化することはできないためです。

どうすればこれを実現できますか?このような:

class A
{
public:
    A(int a, int b) : a_(a), b_(b) {};
    int a_, b_;
};

class B : public A
{
public:
    B() : A(0,0) 
    {
    }
};
0
John Dibling