基类实现能否代表接口的纯虚拟方法

Can a base class implementation stand in for a pure virtual method of an interface?

本文关键字:虚拟 方法 接口 实现 基类      更新时间:2023-10-16

>假设我有CFooer,它实现了方法void foo((。

然后我有虚拟虚空 foo(( = 0 的 ISomething。

我现在创建一个类:

class CSuperFoo : public CBase, public CFooer, public ISomething
{
};

当我实例化 CSuperFoo 时,我会得到一个无法实例抽象类错误,还是会使用 CFooer 的实现来满足 ISomething。如果这不起作用,为什么不起作用?

谢谢

您必须

在派生类中提供一个实现CSuperFoo才能创建它的对象,否则它将是一个抽象类。

基类ISomethingfoo()的方法需要在派生类CSuperFoo中显式重写,因为编译器看不到类 CFooerISomething::foo() 的方法之间的任何关系,因为 CFooerISomething 之间没有关系,所以它要求在派生类中实现的特定方法,以便它不再是抽象类。

不适用于 Ideone

如果CFooer实际上继承自ISomething,我相信它应该可以正常工作(我没有测试它(。如果它没有虚拟继承,那么它将被视为两种不同的方法,并且需要覆盖抽象方法。

通常,C++人们不使用继承来实现接口,乍一看,这段代码似乎是一种代码气味。如果您向我们提供更多详细信息,可能会有更好、更C++惯用的方法。

简短回答:不,您无法实例化它。

解释:首先,不能实例化抽象类。抽象类是具有纯虚函数的类。你知道的。现在,从这个抽象类派生的任何类在实现这些纯虚函数之前仍然是抽象的。因此,如果 I SuperFoo 继承自 ISomething,那么在它实现 ISomething 中声明的纯虚函数之前,SuperFoo 将保持抽象。现在你可能会认为,CFooer 实现了在 ISomething 中声明的纯虚函数,因此 SuperFoo 实现了它。但是如果你认为那么你忘记了一些东西,即函数隐藏,看,现在纯虚函数的SuperFoo定义从ISomething的函数原型中隐藏,因此需要定义纯虚函数。所有这些都假设CFooer继承自ISomething,因为它具有相同的函数定义,如果不是,那么您做错了,实际上您可能甚至应该处于这种情况。

还有一点要补充的是,如果 CFooer 确实继承了 ISomething,那么 ISomething 就没有必要成为 CSuperFoo 的一部分。您可以简单地将CFooer中定义的函数声明为虚拟函数,然后在SuperFoo中再次实现它。根据代码的次要细节,还可能出现更多问题,例如对虚拟继承的需求。

根据C++常见问题解答,这是"合法的,但不道德的"。

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.8

本质上,您将通过在派生类中实现具有相同名称foo的虚拟或非虚拟方法来"隐藏"CFooer::foo((。

这里有不同的情况需要考虑。第一件事是你的句子的确切含义是什么:CFooer 实现了方法 void foo((。如果这句话的意思是ISomething中有一个与纯抽象函数具有相同签名的函数,那么这不是在接口上实现该函数。

另一方面,如果 CFooer 派生自ISomething接口,则CFooer::foo确实实现了该函数并提供最终覆盖器。问题是CSuperFoo派生自CFooerISomething,它包含两个不同的类型为ISomething的子对象,CFooer只为其中一个提供最终覆盖器CSuperFooer仍然是抽象的。

如果是这种情况,将CFooerCSuperFooer中的继承从ISomething更改为虚拟将解决此问题(虚拟继承的设计使得即使在层次结构树的不同级别或分支中提到该类型,所有标记为virtual的类型都表示单个唯一对象。 CSuperFooer将有一个ISomething子对象,最终覆盖器可以是 CFooer 的覆盖器。