4

Stroustrup の新しい本を読んでいたところです。Chapter 22.2.2 で、彼は dynamic_cast の問題について議論しています。

これを自分でテストするために書いたコードは次のとおりです。

class Storable  
{
public:
    int i;
    virtual void r() {};
    Storable()  
    {
        i = 1;
    };
};

class Component:public virtual Storable
{
public:
    Component()  
    {
        i = 1;
    };
};

class Receiver:public Component
{
public:
    Receiver()  
    {
        i = 2;
    };
};

class Transmitter:public Component
{
public:
    Transmitter()  
    {
        i = 3;
    };
};

class Radio:public Transmitter
{
public:
    Radio()  
    {
        i = 4;
    };
};


int _tmain(int argc, _TCHAR* argv[])
{
    Radio *r = new Radio();
    Storable *s1 = dynamic_cast<Storable*>(r);

    Component *c = dynamic_cast<Component*>(s1);  // this should be 0 but it is not!

    return 0;
}

Stroostrup は、どのバージョンの Storable が参照されているかを知ることができないため、c は nullptr であるべきだと説明しています。ただし、有効なポインターとして取得します。

これについては Stroustrup がおそらく正しいと思いますが、私が何を微妙に見逃しているのかわかりません。他の誰かがそれを見つけることができますか?

4

1 に答える 1

3

そこに曖昧さは見えません。例を正しく転写しましたか? C++11、[expr.dynamic.cast]§8 の引用 (を使用dynamic_cast<C*>(v)):

...vが最も派生したオブジェクトの public 基本クラス サブオブジェクトを指している (参照している) 場合、最も派生したオブジェクトの型は型 の基本クラスを持ちC、それは明確であり、結果はそのサブオブジェクトpublicを指している (参照している)C最も派生したオブジェクトの。

タイプ の最も派生したオブジェクトのサブオブジェクトを指すあなたvはです。タイプinの基本クラス サブオブジェクトは 1 つだけで、パブリックであるため、動的キャストは成功するはずです。s1StorableRadioComponentRadio

Radioからも派生した場合はあいまいになりReceiverます。おそらくあなたはそれを逃しましたか?

于 2013-09-30T09:58:19.847 に答える