なぜこれができないのですか?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
なぜこれができないのですか?
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.
{
}
};
a
や内部化ができないということではありません。これらはのメンバーではないため、初期化できません。それらを公開または保護した場合は、の本文に割り当てることができます。b
B::B()
class B
B::B()
a
and b
...」と入力し、残りの文が意味をなさないことを確認せずに「You ca n't initialize ...」に変更しました。投稿を編集しました。
どういうわけか、誰も最も簡単な方法を挙げていません:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
初期化子リスト内の基本メンバーにはアクセスできませんが、コンストラクター自体は、他のメンバーメソッドと同様に、基本クラスのpublic
とprotected
メンバーにアクセスできます。
B
が割り当てられると、最初にデフォルトで初期化され、次にB
コンストラクター内で割り当てられます。しかし、コンパイラーはこれを最適化できると私は思います。
class A
はa
、b
初期化に依存することはできません。class C : public A
たとえば、の実装では、呼び出しa=0;
を忘れてa
初期化されないままになる場合があります。
class A { int a = 0;};
)、または基本クラスのコンストラクターでフィールドをデフォルトで初期化することをお勧めします。サブクラスは、必要に応じて、コンストラクターでサブクラスを再初期化できます。
# 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クラスコンストラクター呼び出しを介してこれらの値をプッシュする場合の実用的な例です。
これはまれなケースでは便利ですが(そうでない場合は、言語で直接許可されていました)、メンバーイディオムのベースを確認してください。これはコードフリーのソリューションではありません。継承のレイヤーを追加する必要がありますが、それで仕事が完了します。ボイラープレートコードを回避するには、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)
{
}
};