I am learning C++ and I am confused about the multiple inheritance and the interface classes.
I want to have a class that inherits from several others. Also, I want to use that derived class through an interface. So I suppose, the derived class should extend the base classes, and the derived interface should extend the base interfaces. I would have done that in other languages, but I think C++ does not work like that.
This is the code I thought should work:
#include <iostream>
using std::cout;
using std::endl;
class
Base1Itf
{
public:
virtual void blue() = 0;
};
class
Base1Abs
:
public Base1Itf
{
public:
void blue()
{
cout << "blue" << endl;
}
};
class
DerivedItf
:
public Base1Itf
{
public:
virtual void red() = 0;
};
class
Derived
:
public Base1Abs,
public DerivedItf
{
public:
void red()
{
cout << "red" << endl;
}
};
int main()
{
DerivedItf* d = new Derived();
d->red();
d->blue();
delete d;
return 0;
}
This is the compiler error I get:
src/test.cpp: In function ‘int main()’:
src/test.cpp:49:30: error: invalid new-expression of abstract class type ‘Derived’
DerivedItf* d = new Derived();
^
src/test.cpp:35:2: note: because the following virtual functions are pure within ‘Derived’:
Derived
^~~~~~~
src/test.cpp:10:16: note: virtual void Base1Itf::blue()
virtual void blue() = 0;
^~~~
In the example only a base class is implemented, but there will be many more.
What I am doing wrong? Thank you.
EDIT
If I remove the Base1Abs inheritance of Base1Itf for avoiding the Diamond Problem, the compiler shows the same error.
This is the well known diamond problem in C++. This is how you solve it:
#include <iostream>
using std::cout;
using std::endl;
class Base1Itf {
public:
virtual void blue() = 0;
virtual ~Base1Itf() { }
};
class Base1Abs : virtual public Base1Itf {
public:
void blue() override {
cout << "blue" << endl;
}
virtual ~Base1Abs() { }
};
class DerivedItf : virtual public Base1Itf {
public:
virtual void red() = 0;
virtual ~DerivedItf() { }
};
class Derived : public Base1Abs, public DerivedItf {
public:
void red() override {
cout << "red" << endl;
}
virtual ~Derived() { }
};
int main() {
DerivedItf* d = new Derived();
d->red();
d->blue();
delete d;
return 0;
}
It is also recommended to use virtual destructors in inheritance.
You see, what happens here is that classes Base1Abs
and DerivedItf
both inherit a copy of blue
. Now, when you inherit another class Derived
from these 2, that class inherits 2 copies of blue
and then the compiler starts wondering which copy is to be called. So, you inherit the 2 classes virtually resulting in only one copy of blue
getting inherited