2011-12-12 14 views
32

仮想メソッドを使用しないで継承することはできますか?コンパイラは、次のコードは多相ではないと言っています。クラスがポリモーフィックでないため、ダウンキャストできませんか?

例:私たちはBオブジェクトへAオブジェクトからダウンキャストしようとしている別のクラスで

Class A(){ 
    int a; 
    int getA(){return a;}; 
} 


Class B(): A(){ 
    int b; 
    int getB(){return b;}; 
} 

A *a; 
B *b = dynamic_cast<B*>(a) 

が、これは次のエラー得られます。

cannot dynamic_cast ... (source type is polymorphic) 
+1

'a'はポインタではありません。これはあなたのコードの中にありますか? – littleadv

+0

申し訳ありませんが、実際にはポインタです。 – wbarksdale

+0

コンパイル時間または実行時間はエラーですか?実行時間の場合、IMHOは予想される動作です。 – littleadv

答えて

56

構文エラーに耐えない、できませんdynamic_cast非多型型です。 static_castは、実際にターゲットタイプのオブジェクトであることがわかっている場合は、この場合に使用するキャストです。

理由:static_castは基本的にコンパイル時にコンパイル時に「入力を出力にキャストできますか?」というチェックを行います。これは、ポインタ(または参照)の継承階層を上または下にキャストしている場合に使用できます。しかし、このチェックはコンパイル時にのみ行われ、コンパイラは自分が何をしているかを知っていると仮定します。

dynamic_castは、ポインタまたは参照キャストの場合にのみ使用できます。また、コンパイル時のチェックに加えて、キャストが合法であることを追加の実行時検査で確認します。問題のクラスには少なくとも1つの仮想メソッドが必要です。コンパイラがRTTIをサポートしている場合は、この追加チェックを実行できます。しかし、問題の型に仮想メソッドがない場合、その型は使用できません。

このようなポインタを渡す場合は、最も単純なケースで、おそらく価値があります。基本クラスのデストラクタを仮想にすることを検討することです。動的キャストを使用できるほか、基本クラスのポインタが削除されたときに適切なデストラクタを呼び出すこともできます。

+0

知識に感謝します。それはうまくいった。 – wbarksdale

2
A a; 
B *b = dynamic_cast<B*>(a) 

ここで、aはオブジェクトであり、bはポインタです。

実際、アップキャストとダウンキャストは両方ともC++で許可されています。しかし、ダウンキャストを使用するときは、2つのことに注意する必要があります。 1スーパークラスには少なくとも1つの仮想メソッドが必要です。 2スーパークラスはサブクラスより "小さい"ため、メモリオブジェクトを慎重に使用する必要があります。

4

はい、非多型のdynamic_castは許可されません。基本クラスは少なくとも1つの仮想メソッドを持たなければならない。そのクラスだけが多態性として呼び出すことができます。

この記事では、同様の例を説明しますhttp://www.cplusplus.com/doc/tutorial/typecasting/

+0

Daveはすばらしい答えを出しました。私は彼の投稿にコメントする特権を持っていません。だから私はここでコメントしている。 –

18

あなたは成功しdynamic_cast演算子を適用するrun-time type information (RTTI)のクラスに少なくとも1つの仮想メソッドを必要としています。

11

デストラクタを仮想にするだけです(常に安全のために任意のクラスに対して行います)。

+7

はどのクラスでもなく、基本クラスを意図したクラス – ParokshaX

関連する問題