Why can't I use inheritance to implement an interface in C++? [duplicate]

时光毁灭记忆、已成空白 提交于 2019-11-26 17:24:42

问题


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::foo that has the same name and signature as A::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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!