方法 1:static_cast
を使用して基本クラスを使用して派生クラスを初期化できますが、これは不完全な派生オブジェクトになります
。
ソース
static_cast は、派生クラスからそのベースへの変換だけでなく、基本クラスからその派生クラスへの変換も、関連するクラスへのポインター間の変換を実行できます。これにより、適切なオブジェクトが変換された場合に少なくともクラスに互換性があることが保証されますが、実行時に、変換されるオブジェクトが実際に変換先の型の完全なオブジェクトであるかどうかを確認するための安全性チェックは実行されません。したがって、変換が安全であることを確認するのはプログラマの責任です。
次の例を参照してください。
ここでは、「bInt」というパブリック変数を持つ基本クラスを記述します。
class B {
public:
int bInt;
};
ここで、「dInt」という独自の変数を持つサブクラスを作成します
class D: public B {
public:
int dInt;
};
ここに、基本クラスの新しいインスタンスがあります。ベース オブジェクトの変数を初期化します。
B * baseObj = new B;
baseObj->bInt = 1;
ここでは、基本クラスを使用して、 を使用して派生クラスを宣言および初期化しstatic_cast
ます。この時点で、*derivedObj
は不完全であることに注意してください。具体的にderivedObj->dInt
は、未定義の値があります。
D * derivedObj = static_cast<D*>(baseObj);
D は B から派生しているため、bInt
変数もあります。また、以前static_cast
は を初期化していたため*derivedObj
、 の値もの値bInt
と同じであり、したがってこれらは等しいです。*baseObj
bInt
if(baseObj->bInt == derivedObj->bInt)
{
display("it's equal");
}
ただし、基本クラスにはdInt
変数がないため、この変数は初期化されないままになり、この手順の結果は未定義になります。
int myNum = derivedObj->dInt;
static_cast を使用する場合は、派生クラスのメンバーを必ず初期化してください。とにかくそうするのは良い習慣です。
static_cast を使用する場合、B のすべてのメンバーを知る必要はありません。D は自動的に B のすべてのメンバー値を持ちます。しかし、不完全なオブジェクトを作成しているため、あなたがやろうとしていることは危険です。
方法 2:本当に B をサブクラス化する必要がある場合は、D のコンストラクターを B* を受け取り、次のようにコピーして B を初期化するコンストラクターとして記述します。
D(const B &pass) : B(pass)
したがって、型 D のオブジェクトを宣言して初期化する場合は、次のようにします。
B *baseObj = new B;
D *derivedObj = new D(*baseObj);
要約すると、次の 2 つの選択肢があります。
- B をサブクラス化し、static_cast を使用して D を初期化します。D のメンバー変数を必ず初期化してください。
- B をサブクラス化し、B を受け取り、それを B のコピー コンストラクターに渡すコンストラクターを記述します。
これらの方法はどちらも同じ結果になりますが、違いは、プログラムが舞台裏でこれを行う方法です。
残念ながら、あなたの例でd=b
は、基本クラスを派生クラスに割り当てようとしているため、使用は「違法」(?) です。b=d
代入演算子は、初期化された givenなど、逆にのみ使用できd
ます。
独自の代入演算子を作成してそれを行うこともできますが、個人的にはお勧めしません。