私の基本クラスは次のとおりです。
class point //concrete class
{
... //implementation
}
class subpoint : public point //concrete class
{
... //implementation
}
ポイントオブジェクトからサブポイントオブジェクトにキャストするにはどうすればよいですか?次の3つすべてを試しました。
point a;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
subpoint b = (subpoint)a;
これらのキャストの何が問題になっていますか?
ポイントオブジェクトからサブポイントオブジェクトにキャストするにはどうすればよいですか?
できません。 point
に変換演算子があるか、subpoint
に変換コンストラクタがない場合を除きます。この場合、キャストを必要とせずにオブジェクトタイプを変換できます。
参照されたオブジェクトが実際にあった場合、point
reference(またはポインター)からsubpoint
reference(またはポインター)にキャストできます。タイプsubpoint
の:
subpoint s;
point & a = s;
subpoint & b1 = static_cast<subpoint&>(a);
subpoint & b2 = dynamic_cast<subpoint&>(a);
最初 (static_cast
)の方が危険です。変換が有効かどうかのチェックは行われないため、a
がsubpoint
を参照しない場合は、b1
の動作は未定義です。
二番目 (dynamic_cast
)の方が安全ですが、point
が多態性である場合(つまり、仮想関数がある場合)のみ機能します。 a
が互換性のないタイプのオブジェクトを参照している場合、例外がスローされます。
動的キャストの目的は、「オブジェクトが階層内の特定のタイプかどうかを実行時に確認する」ことです。それでは、あなたが持っているものを見てみましょう:
対照的に、これはうまくいったでしょう:
subpoint c;
point *a = &c;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
最初の例では、_dynamic_cast
_は、基本クラスに少なくとも1つの仮想メソッドがある場合にのみ機能します。また、オブジェクトが実際にキャストしようとしている型ではない場合、結果はNULLになります。
2番目の例では、a
ではなく_&a
_が必要ですが、修正すると、オブジェクトタイプが間違っているため、未定義の動作が発生します。
3番目の例では、コピーの作成中に変換を行うために、point
のoperator subpoint()
メソッドが必要です。
全体として、point
はsubpoint
ではないため、これは機能しません。逆のみが真です。ただし、他にも問題があります。
順番に:
_subpoint* b = dynamic_cast<subpoint*>(&a);
_
_dynamic_cast
_は、ポリモーフィック型、つまり少なくとも1つの仮想関数を宣言する型でのみ機能します。私の推測では、point
には仮想関数がないため、_dynamic_cast
_では使用できません。
_subpoint* b = (subpoint*)a;
_
このキャストが機能するためには、point
が_subpoint *
_への変換演算子を宣言する必要があります(例:point::operator subpoint *()
)。
_subpoint b = (subpoint)a;
_
このキャストが機能するためには、ポイントはsubpoint
への変換演算子を宣言する必要がありますorsubpoint
は、point
から変換可能なパラメーターを取得するコンストラクターを持っている必要があります。
これらのキャストの何が問題になっていますか?
あなたがそれらをしようとするという事実。 point
はsubpoint
ではありません。うまくいったとしたら驚きます。
a
をsubpoint
にすることはできません。その実装はありません。