web-dev-qa-db-ja.com

クラスがポリモーフィックではないため、ダウンキャストできませんか?

仮想メソッドなしで継承することは可能ですか?コンパイラは、次のコードはポリモーフィックではないと言っています。

例:

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


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

別のクラスでは、AオブジェクトからBオブジェクトにダウンキャストしようとしています。

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

ただし、これにより次のエラーが発生します。

 cannot dynamic_cast ... (source type is polymorphic)
42
wfbarksdale

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

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

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

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

69
Dave S

Dynamic_cast演算子を正常に適用するには、run-time type information (RTTI)のクラスに少なくとも1つの仮想メソッドが必要です。

26
tenorsax

デストラクタを仮想化するだけです(常に安全のためにどのクラスでも実行します)。

13
user993954

はい、非多相型のdynamic_castは許可されていません。基本クラスには、少なくとも1つの仮想メソッドが必要です。その場合のみ、そのクラスをポリモーフィックとして呼び出すことができます。

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

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

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

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

2
tyger