Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you implement polymorphic behaviour with multiple inheritance?

I have never used multiple inheritance but while reading about it recently I started to think about how I could use it practically within my code. When I use polymorphism normally I usually use it by creating new derived instances declared as base class pointers such as

 BaseClass* pObject = new DerivedClass();

so that I get the correct polymorphic behaviour when calling virtual functions on the derived class. In this way I can have collections of different polymorphic types that manage themselves with regards to behaviour through their virtual functions.

When considering using multiple inheritance, I was thinking about the same approach but how would I do this if I had the following hierarchy

 class A {
     virtual void foo() = 0;
 };
 class B : public A {
     virtual void foo() {
         // implementation
     }
 };

 class C {
     virtual void foo2() = 0;
 };
 class D : public C {
     virtual void foo2() {
         // implementation
     }
 };

 class E : public C, public B {
     virtual void foo() {
         // implementation
     }
     virtual void foo2() {
         // implementation
     }
 };

with this hierarchy, I could create a new instance of class E as

 A* myObject = new E();

or

 C* myObject = new E();

or

 E* myObject = new E();

but if I declare it as a A* then I will lose the polymorphism of the class C and D inheritance hierarchy. Similarly if I declare it as C* then I lose the class A and B polymorphism. If I declare it as E* then I cannot get the polymorphic behaviour in the way I usually do as the objects are not accessed through base class pointers.

So my question is what is the solution to this? Does C++ provide a mechanism that can get around these problems, or must the pointer types be cast back and forth between the base classes? Surely this is quite cumbersome as I could not directly do the following

 A* myA = new E();
 C* myC = dynamic_cast<C*>(myA);

because the cast would return a NULL pointer.

like image 944
mathematician1975 Avatar asked Dec 21 '22 18:12

mathematician1975


1 Answers

With multiple inheritance, you have a single object that you can view any of multiple different ways. Consider, for example:

class door { 
   virtual void open();
   virtual void close();
};

class wood { 
    virtual void burn();
    virtual void warp();
};

class wooden_door : public wood, public door {
    void open() { /* ... */ }
    void close() { /* ... */ }
    void burn() { /* ... */ }
    void warp() { /* ... */ }
};

Now, if we create a wooden_door object, we can pass it to a function that expects to work with (a reference or pointer to) a door object, or a function that expects to work with (again, a pointer or reference to) a wood object.

It's certainly true that multiple inheritance will not suddenly give functions that work with doors any new capability to work with wood (or vice versa) -- but we don't really expect that. What we expect is to be able to treat our wooden door as either a door than can open and close, or as a piece of wood that can burn or warp -- and that's exactly what we get.

like image 142
Jerry Coffin Avatar answered Dec 24 '22 02:12

Jerry Coffin