Multiple inheritance: cannot instantiate abstract class

Viewed 290

I have this:

class Base {
public:
    Base() {};
    virtual ~Base() = default;

    virtual void Draw() = 0;
};

class Derived_1 {
public:
    Derived_1() {};
    void Draw() { std::cout << "Draw()" << std::endl; };
};

class Derived_2 : public Base, public Derived_1 {
public:
    Derived_2() {};
    ~Derived_2() {};        

    //void Draw() { Derived_1::Draw(); }; <<<<<===--- This works well
};

class Derived_3 : public Derived_2 {
public:
    Derived_3() {};
    ~Derived_3() {};        
};

int main()
{
    Base* d = new Derived_3();
    d->Draw();

    return 0;
}

I got an error like "pure virtual function "Base::Draw" has no overrider". I think the problem is Derived_2 has two Draw() functions, one of which is virtual. However, I don't know how to fix this without adding wrapper function Draw() in Derived_2 class. Is it possible?

4 Answers

When you give your Derived_2 class multiple inheritance (i.e., it derives from both Base and Derived_1) you are saying that it inherits the member functions from both base classes.

In this case, that will mean that it has two (different) Draw members with the same signatures. Thus, the pure virtual Draw function derived from Base will not be overriden by that derived from Derived_1.

In fact, if you use Derived_3* d = new Derived_3(); in place of your first line of main(), as suggested, you will still get the "cannot instatiate abstract class" error, plus another one along the lines of "amibuguous access of Draw()".

Your commented-out line, void Draw() { Derived_1::Draw(); }; in the Derived_2 class does two things: (1) It resolves the ambiguity in any later call to Draw() from a Derived_2 class; and (2) it provides a viable override of the pure-virtual Draw function of the Base class.

The two Draw functions are distinct, despite the similarities in name and signature. They could just as well have two different names. Base and Derived_1 are unrelated, so Derived_1's Draw cannot override Base's.

If Base::Draw was not pure virtual, the call to d->Draw() in main would be ambiguous, because the compiler would not know which draw to call.

The solution is what you have commented out: provide a Draw in Derived_2 that will call the one in Derived_1. (Not relevant here, but in the alternative where Base::Draw is not pure virtual, Derived_2::Draw might need to call the Draw function in both base classes.)

I think your problem is that you defined d as class “Base”, instead of class “Derived_3”, so even though you used the derived_3 constructor the compiler is looking for a definition of draw under “Base.”

you have 2 functions with the same name and arguments, that is never good. try either changing the name of one of the Draw() functions or, if you really want the same name, making Derived_1 inherit from Base

Related