-1
class A
{
};

class B:public A
{
};
int main()
{
    A a;
    B b;
    A *ap = &b;
    B *bp = dynamic_cast<B*>(ap);
    if(bp!= NULL)
       cout<<"Pass"<<endl;
    else
       cout<<"Fail"<<endl;
    return 0;
}

動的キャストを実行する場合、なぜクラスAを仮想にする必要があるのですか?

4

3 に答える 3

7

dynamic_castとは動​​作が異なりstatic_castます。a の結果static_castは常にポインターです。ただし、キャストが正しくない場合 (指定されたポインターが元の型ではなかった場合)、キャストの結果は未定義です。ポインタは必ずしも有効ではありません。static_castしたがって、 ;を使用して派生クラスにキャストする場合、ある程度の不確実性があります。間違ったものにキャストするのを防ぐメカニズムはありません。

dynamic_castキャストが正しい場合は有効なポインターを返し、正しくない場合は null ポインターを返します。したがって、結果はすべてのケースで明確に定義されています。これを行うには、動的dynamic_castでなければなりません。これは、キャスト先の型が正当なキャスト操作であるかどうかを確認するために、ポインターに対してランタイム チェックを実行する必要があることを意味します。

C++ は、「使用した分だけ支払う」という原則により、非仮想型のキャストを禁止しています。仮想関数を持たない型は、通常、その基底クラスによって渡される型ではありません。仮想を使用しない継承は、主に既存の実装を使用することであり、関数を特殊化することではありません。仮想デストラクタのような単純なものでも十分です。

必要な機械dynamic_castはゼロではありません。そのため、「使用した分だけ支払う」という原則の下で、有用なクラスだけが料金を支払います。IE: 仮想のクラス。

于 2012-08-06T03:36:21.247 に答える
1

出力は次のようになります。

エラーxxxx:へのパラメータが無効dynamic_castです。クラスは非ポリモーフィックタイプです。

の仕様であるため、クラスは多形である必要がありますdynamic_cast。内部的には、dynamic_cast仮想テーブルポインターをチェックしますが、これは実装の詳細です。

この場合に使用できますstatic_cast

于 2012-08-06T03:22:49.300 に答える
0

virtual多形の鍵です。仮想関数とは、派生クラスによって「オーバーライド可能」であることを意味します。それ以外の場合、クラス間にポリモーフィズムはなく、継承のみがあります。クラスがポリモーフィックでない場合、 はdynamic_cast使用できません。

于 2013-12-20T11:29:23.527 に答える