问题
Possible Duplicate:
Implementing abstract class members in a parent class
Why does C++ not let baseclasses implement a derived class' inherited interface?
Considering these objects:
struct A
{
virtual void foo() = 0;
};
struct B
{
void foo() { /* neat implementation */ }
};
I wonder why --compiler-wise-- the following object is considered abstract:
struct C : B, A
{
using B::foo; // I tried my best to make the compiler happy
};
The compiler won't let me do this:
A* a = new C;
Visual Studio 2010 says:
'C' : cannot instantiate abstract class due to following members: 'void A::foo(void)' : is abstract : see declaration of 'A::foo'
g++ 4.6.3 says:
cannot allocate an object of abstract type ‘C’ because the following virtual functions are pure within ‘C’: virtual void A::foo()
I guess this is allowed in C#, but I don't know the involved mecanism(s) -- I am just being curious.
回答1:
struct B is implementing a function that happens to be called foo and takes no arguments. That function has obviously absolutely no relation to A::foo. So when struct C derives from both A and B, it ends up having inherited:
- the responsibility to provide an implementation for
A::foo - a method
B::foothat has the same name and signature asA::foo, but is not related to it in any way
I think the problem is obvious. You are trying to use A as the equivalent of a C# interface, but there is no way to express that concept in C++.
Now the using directive also does not help here because all it does is bring B::foo into the scope of C, meaning that it tells the compiler it should consider B::foo as a candidate for resolving the name foo when the latter is encountered inside class C. Unfortunately, that's also unrelated to the responsibility of implementing pure virtual methods.
回答2:
Unfortunately, this does not quite do what you want.
A using directive is just about bringing some names into the scope it is used. virtual methods need be overriden, and just bringing names is not considered overriding.
The truth of the matter is that C++ does not support delegation directly. There is just this slight twist of bringing names into scope explicitly.
回答3:
To resolve this one, you need to implement your own foo() within C and explicitly call the B function--effectively forwarding A::foo to B::foo within C:
struct C : B, A
{
virtual void foo() {
// Override A::foo by forwarding to B::foo:
B::foo();
}
};
It makes sense at some level--there is no inherent relation between A::foo() and B::foo()--you have to explicitly establish one within C.
回答4:
I guess this is allowed in C#
C++ is not C#.
virtual void foo() and void foo() are two different methods.
When you derive from both A and B, you get access to two methods: virtual A::foo and non-virtual B::foo. And virtual A::foo is abstract. Hence the compiler error.
来源:https://stackoverflow.com/questions/10533772/why-cant-i-use-inheritance-to-implement-an-interface-in-c