Multiple inheritance casting from base class to different derived class

16,644

Solution 1

No. This is not possible (direct casting from A* to B*).

Because the address of A and B are at different locations in class C. So the cast will be always unsafe and possibly you might land up in unexpected behavior. Demo.

The casting should always go through class C. e.g.

A* pa = new C();
B* pb = static_cast<C*>(pa);
                   ^^^^ go through class C

Demo

Solution 2

The way to go from any type to any other is dynamic_cast. But it requires the object to be polymorphic. In general this requires a v-table to be associated to both A and B, so: if A and B have at least one virtual function, and RTTI is not disable,

A* pa1 = new C;
A* pa2 = new A;

B* pb1 = dynamic_cast<B*>(pa1);
B* pb2 = dynamic_cast<B*>(pa2);

will result in pb2 to be null, and pb1 to point to the B part of the object containing *pa1 as its A part. (The fact it's C or whatever other derived from those two bases doesn't matter).

Otherwise, where all needs to be static, you have to go through C

B* pb = static_cast<B*>(static_cast<C*>(pa));

Note that static_cast<B*>(pA) cannot compile, being A and B each other unrelated.

Solution 3

Yes, you should first static_cast object to C*, then you can static_cast it again to B (although this last cast is not needed, since is a standard conversion). I'm not sure if static_casting object directly to B would work, try and see if you get compiler errors. reinterpret_casting object to B would get you a runtime crash, since A and B would have different addresses if they are both non-empty.

Edit After you changed the question, it is no longer possible to do what you want. You need to know the correct path up and down the inheritance tree, as casting in a scenario with multiple inheritance with non-empty classes implies shifts in the pointer.

Share:
16,644

Related videos on Youtube

Andrew
Author by

Andrew

Software Development Engenier, Microsoft http://ru.linkedin.com/pub/andrew-vorobyev/48/2b2/bab

Updated on April 27, 2020

Comments

  • Andrew
    Andrew about 4 years

    Let's assume there is such class hierarchy:

    class A //base class
    
    class B //interface
    
    class C : public A, public B
    

    Then C object is created:

    A *object = new C();
    

    Is it possible to cast object to B ?

    Important: I assume I don't know that object is C. I just know that it implements interface B

  • Andrew
    Andrew almost 13 years
    Thanks. The unexpected behavior is exactly what i had)
  • Andrew
    Andrew almost 13 years
    But i can't figure out why dynamic_cast went ok
  • iammilind
    iammilind almost 13 years
    @Andrew, dynamic_cast<C*> is also valid and it will work (provided the classes are polymorphic); because C is really a subclass of A. However, in this case static_cast<C*> will be a better idea as it happens at compile time.
  • Den-Jason
    Den-Jason about 4 years
    "The way to go from any type to any other is dynamic_cast." This is incorrect; to resolve a downcast you need to use dynamic_cast, to resolve an upcast you can use static_cast. You can also use dynamic_cast, but it is unnecessary.
  • Emilio Garavaglia
    Emilio Garavaglia about 4 years
    I stated "from any to any". If you distinguish down from up, it will be "any to some", IMHO. And then: what's the point to say it's "incorrect" if you than admit it works?
  • Hill
    Hill almost 3 years
    I use reinterpret_casting, no crash happens, why?