4

私は少し前にこれらの質問をしました: 基本クラスから異なる派生クラスへの多重継承キャスト

しかし、私はまだ答えを理解しているかどうかわかりません。問題は、以下のコードは有効ですか?

#include <iostream>

using namespace std;

struct Base
{
    virtual void printName() 
    {
        cout << "Base" << endl;
    }
};

struct Interface
{
    virtual void foo()
    {
        cout << "Foo function" << endl;
    }
};

struct Derived : public Base, public Interface
{
    virtual void printName()
    {
        cout << "Derived" << endl;
    }
};

int main(int argc, const char * argv[])
{
    Base *b = new Derived();
    Interface *i = dynamic_cast<Interface*>(b);
    i->foo();

    return 0;
}

コードは私が望むように機能します。しかし、私が理解しているように、前の質問によれば、そうすべきではありません。したがって、そのようなコードが有効かどうかはわかりません。ありがとう!

4

5 に答える 5

5

有効なコードです。

なんで?
なぜならdynamic_cast、ポイントされているオブジェクトが実際にキャスト先のタイプであるかどうかを示しているからです。
この場合、ポイントされている実際のオブジェクトはタイプであり、タイプDerivedの各オブジェクトDerivedもタイプInterface(からDerived継承するInterfaceため)であるため、dynamic_castは有効であり、機能します。

于 2012-05-01T16:38:40.593 に答える
3

関連するクラスに少なくとも1つの仮想メソッド(仮想デストラクタである可能性があります)がある限り、そのまま使用dynamic_castすることは正しく、準拠するコンパイラで機能します。

とは異なりstatic_castdynamic_castタイプ情報の実行時チェックを許可できます。ただし、これは失敗する可能性があることも意味し、NULLポインタをキャストするために使用するとを返します。キャスト結果が成功しない可能性がある場合は、キャスト結果を確認する必要があります。

あなたが尋ねた前の質問では、クラスには仮想メソッドがなく、dynamic_castそのようなクラスでは使用できないため、機能しませんでした。

于 2012-05-01T16:39:00.980 に答える
0

成功した場合dynamic_cast、それは有効です。実行時にすでに型安全性チェックを実行しています。

于 2012-05-01T16:36:29.093 に答える
0

次のことを考慮してください。

Base *b = new B();
Interface *i = dynamic_cast<Interface *>( b );

これは機能する必要がありますか?いいえ。理由は、BaseInterfaceは相互に関連していないためです。ただし、へのポインタがあなたBaseから派生したオブジェクトを指しているという特殊なケースでは、ポインタをInterfaceキャストして(コンパイラにオブジェクトを型と見なすように誘導しますInterface) 、演算子Baseの結果をさらに使用できます。dynamic_cast

于 2012-05-01T16:40:00.063 に答える
0

標準が5.2.7パラグラフ4(C ++ 2003標準)でそう言っているので、あなたのコードは有効です:

実行時チェックは、論理的に次のように実行されます。

— vが指す(参照する)最も派生したオブジェクトで、vがTオブジェクトのパブリックベースクラスサブオブジェクトを指す(参照する)場合、およびT型の1つのオブジェクトのみが指すサブオブジェクトから派生する場合(参照)vによって参照されると、結果はそのTオブジェクトへのポインター(参照する左辺値)になります。

—それ以外の場合、vが最も派生したオブジェクトのパブリック基本クラスサブオブジェクトを指し(参照)、最も派生したオブジェクトのタイプに、明確でパブリックなタイプTの基本クラスがある場合、結果は次のようになります。最も派生したオブジェクトのTサブオブジェクトへのポインタ(参照する左辺値)。

—それ以外の場合、実行時チェックは失敗します。

実行時チェックでの「最も派生したオブジェクト」の使用に注意してください。あなたの例では、あなたのオブジェクトの「最も派生したオブジェクト」Base *bDerivedオブジェクトです。クラスはとDerivedの両方からパブリックに継承するため、この特定のケースでは、そのオブジェクトをにキャストできます。BaseInterfaceBase*Interface*

于 2012-05-01T16:45:29.667 に答える