C++ allows for multiple inheritence. While this is a strong feature, it is also a dangerous one if care is not taken.

To start, this is what we might expect of multiple inheritence relationship

Might Expect Class Diagram

But this is what actually happens:

As you can see, the Bernies Mountian and Golden Retriever classes each have their own dog class instead of sharing one. Here is a representation in ram:

Ram Representation

Problem one is that if we want a pointer to a Hybrid objects Dog object, the compiler will not know which dog to use.

Hybrid h;
Dog* d = &h; //Error, Dog is ambiguous

Clearing ambiguety is as easy as stating which class pointer to use:

BernieMountain bPointer = &h;
GoldenRetriever rPointer = &h;
Dog* dogPointer = (GoldenRetriever)&h; //Point to the golden retirever dog class

Performing the above is known as upcasting and it happens at compile time so there is not runtime hit

Going the otherway Link to heading

Upcasting can be done but what about downcasting?

Hybrid* downCastResult = dynamic_cast(dogPointer);

This is how you would perform a down cast. It happens at run time

Going from Bernie Mountian to Golden Retriever Link to heading

If you wanted to Bernie Mountain pointer point to the golden retriever, you can if you want, I never explored this topic so it ends here

BernieMountain* bernPointer = dynamic_cast(gPointer);

What if I want to do the original concept? Link to heading

Answer: virtual tags. Virtual tags everywhere! class BernieMountain : virtual public dog {/class stuff/};

It basically looks like this:

Virtual Tag Class Diagram

Ram representation:

Virtual Tag Class Ram Representation

Notes on this: Link to heading

If Dog had an abstract method like bark and it were to be implemented in Bernie but not Golden, Golden will use the Bernie Mountain Bark

If Golden were to implement bark also, the compiler will still to complain about imbiguity. The solution would be implement bark in Hybrid.

Static and Interpret Casts Link to heading

Static casts are a safe and dynamic upcast

Dog* anotherPointer = static_cast(pointerToBernie);

Interpret casts is a dangerous cast that you can use to point to anything

Dog* dogP reinterpret_cast(aBerniePointer);

Reinterpret casts do not check object types so only use them if you know what you are doing. An example of this being ok is if you are sending an object as a byte array over the network

Stuff by Alexander Poganatz. Information may be incorrect

This blog post is licensed under Attribution 4.0 International