Question

I was just reading Stroustrup's new book. In Chapter 22.2.2 he discusses a dynamic_cast issue.

The code I have written to test this myself is as follows:

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 explains that c should be a nullptr as it is not possible to know which version of Storable is being referred to. However, I get it as being a valid pointer.

I would guess that Stroustrup is probably correct on this but I cannot see what subtly I have missed, can anyone else spot it?

Was it helpful?

Solution

I can't see ambiguity there. Have you transcribed the example correctly? Quoting C++11, [expr.dynamic.cast]§8 (using dynamic_cast<C*>(v)):

... if v points (refers) to a public base class subobject of the most derived object, and the type of the most derived object has a base class, of type C, that is unambiguous and public, the result points (refers) to the C subobject of the most derived object.

Your v is s1, which points to a Storable subobject of a most-derived object of type Radio. There's only one base class subobject of type Component in Radio, and it's public, so the dynamic cast should succeed, as it does.

It would be amgiguous if Radio was derived from Receiver as well; perhaps you missed that?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top