为什么我不能使用继承在C++中实现接口?

mis*_*why 8 c++ multiple-inheritance

可能重复:
在父类中实现抽象类成员
为什么C++不允许基类实现派生类的继承接口?

考虑这些对象:

struct A
{
    virtual void foo() = 0;
};

struct B
{
    void foo() { /* neat implementation */ }
};
Run Code Online (Sandbox Code Playgroud)

我想知道为什么 - 编译器 - 明智 - 以下对象被认为是抽象的:

struct C : B, A
{
    using B::foo; // I tried my best to make the compiler happy
};
Run Code Online (Sandbox Code Playgroud)

编译器不允许我这样做:

A* a = new C;
Run Code Online (Sandbox Code Playgroud)

Visual Studio 2010说:

'C':由于以下成员无法实例化抽象类:'void A :: foo(void)':是抽象的:请参阅'A :: foo'的声明

g ++ 4.6.3说:

无法分配抽象类型为"C"的对象,因为以下虚函数在'C'中是纯的:virtual void A :: foo()

我想这在C#中是允许的,但我不知道所涉及的机制主义 - 我只是好奇.

Mat*_* M. 7

不幸的是,这并不是你想要的.

一个using指令是只是把一些名字到它的使用范围.virtual方法需要重写,只是带来名称不被认为是重写.

问题的真相是C++不直接支持委托.将名称明确地引入范围只是一种轻微的转折.


Jon*_*Jon 4

struct B正在实现一个恰好被调用foo且不带参数的函数。该函数显然与 完全没有关系A::foo。因此,当struct CA和派生时B,它最终继承了:

  • 有责任提供实施A::foo
  • B::foo与 具有相同名称和签名A::foo,但与它没有任何关系的方法

我认为问题是显而易见的。您尝试使用AC# 的等效项interface,但无法在 C++ 中表达该概念。

现在,该using指令在这里也没有帮助,因为它所做的只是将其带入B::foo范围C,这意味着它告诉编译器,当在类中遇到后者时,它应该将其B::foo视为解析名称的候选者。不幸的是,这也与实现纯虚拟方法的责任无关。fooC

  • 有人可能会说,“使用”明确地将两者联系起来。它(实际上)没有,但可以。这当然是一厢情愿的想法。 (3认同)