これはC++ではコンパイルされません。
class A
{
};
class B : public A
{
};
...
A *a = new B();
B *b = dynamic_cast<B*>(a);
これはC++ではコンパイルされません。
class A
{
};
class B : public A
{
};
...
A *a = new B();
B *b = dynamic_cast<B*>(a);
dynamic_cast
ポリモーフィック型のみをダウンキャストできるため、標準と言います。
基本クラスにデストラクタを追加することで、クラスを多形にすることができますvirtual
。実際、とにかくおそらくそうすべきです(脚注を参照)。それ以外の場合、ポインタB
を介してオブジェクトを削除しようとすると、未定義動作が発生します。A
class A
{
public:
virtual ~A() {};
};
et voila!
ポリモーフィック型での仮想デストラクタの必要性に関する「ルール」には例外があります。
そのような例外の1つはboost::shared_ptr
、以下のコメントでSteveJessopが指摘したように使用する場合です。仮想デストラクタが必要な場合の詳細については、このハーブサッターの記事を参照してください。
他の人が述べたように:標準はそう言っています。
では、なぜ規格はそう言っているのですか?
タイプが多形でない場合、それはプレーンタイプである可能性があります(または標準の教祖への質問ですか?)。また、プレーンタイプの場合、Cの下位互換性に起因する多くの仮定があります。それらの1つは、開発者が宣言した+必要なアライメントバイトのメンバーのみでタイプが構成されていることです。したがって、余分な(非表示の)フィールドはありません。したがって、Aによって保存されたメモリスペースに、それが実際にBであるという情報を格納する方法はありません。
これは、そのような隠されたものを追加することが許可されているため、多形である場合にのみ可能です。(ほとんどの実装では、これはvtableを介して行われます)。
5.2.7 (動的キャスト) から:
式の
dynamic_cast<T>(v)
結果は、式 v を型 T に変換した結果です。[ ... 他のケースを参照する複数行 ... ]
それ以外の場合、v は多相型 (10.3) へのポインターまたは左辺値でなければなりません。
10.3 (仮想関数) から:
仮想関数を宣言または継承するクラスは、ポリモーフィック クラスと呼ばれます。