问题
I am trying to figure out an interesting multiple inheritance issue.
The grandparent is an interface class with multiple methods:
class A
{
public:
virtual int foo() = 0;
virtual int bar() = 0;
};
Then there are abstract classes that are partially completing this interface.
class B : public A
{
public:
int foo() { return 0;}
};
class C : public A
{
public:
int bar() { return 1;}
};
The class I want to use inherits from both of the parents and specifies what method should come from where via using directives:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
};
When I try to instantiate a D I get errors for trying to instantiate an abstract class.
int main()
{
D d; //<-- Error cannot instantiate abstract class.
int test = d.foo();
int test2 = d.bar();
return 0;
}
Can someone help me understand the problem and how to best make use of partial implementations?
回答1:
You don't have diamond inheritance. The B
and C
base classes of D
each have their own A
base class subobject because they do not inherit virtually from A
.
So, in D
, there are really four pure virtual member functions that need to be implemented: the A::foo
and A::bar
from B
and the A::foo
and A::bar
from C
.
You probably want to use virtual inheritance. The class declarations and base class lists would look like so:
class A
class B : public virtual A
class C : public virtual A
class D : public B, public C
If you don't want to use virtual inheritance then you need to override the other two pure virtual functions in D
:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
int B::bar() { return 0; }
int C::foo() { return 0; }
};
回答2:
You need to make your base classes virtual
in order for them to inherit properly. The general rule is that all non-private member functions and base classes should be virtual
UNLESS you know what you're doing and want to disable normal inheritance for that member/base.
来源:https://stackoverflow.com/questions/5864466/c-multiple-inheritance-why-you-no-work