なぜこれができないのですか?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
a
のメンバーではないため、b
のB
および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.
{
}
};
private
とa
はb
のメンバーであるため、それらは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) {}
};
どういうわけか、誰も最も簡単な方法をリストしませんでした:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
初期化子リストのベースメンバーにはアクセスできませんが、コンストラクター自体は、他のメンバーメソッドと同様に、ベースクラスのpublic
およびprotected
メンバーにアクセスできます。
# 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クラスコンストラクター呼び出しを介してこれらの値をプッシュする場合の実用的な例です。
これはまれなケースでは便利ですが(そうでない場合は、言語で直接許可されます)、 Base from Member idiom を見てください。これはコードフリーのソリューションではありません。継承のレイヤーを追加する必要がありますが、仕事は完了します。定型コードを回避するには、 boostの実装 を使用できます
どうしてできないの?この言語では、派生クラスの初期化子リストで基本クラスのメンバーを初期化することはできないためです。
どうすればこれを実現できますか?このような:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};