继承的函数不算作实现吗?

Does an inherited function not count as an implementation?

本文关键字:实现 函数 继承      更新时间:2023-10-16

我在超类InteractorStyle中定义了一个函数。然后我有另一个类,需要实现该函数(纯虚拟),PointSelector。然后实例化PointSelector的子类PointSelector2D。编译器抱怨我不能实例化一个抽象类,因为没有实现MyFunction()。为什么从InteractorStyle继承的函数不算作这个实现?

#include <iostream>
// I can't change these:
class InteractorStyle
{
  void MyFunction(){}
};
class PointSelector
{
  virtual void MyFunction() = 0;
};
class PointSelector2D : public InteractorStyle, public PointSelector
{
};

int main()
{
  PointSelector2D a;
  return 0;
}

因为使用多重继承,您现在继承了两个不相关的函数,一个来自每个基类。他们只是碰巧彼此有相同的名字(事实上,他们没有;一个称为InteractorStyle::MyFunction,另一个称为PointSelector::MyFunction)。

但是其中一个不覆盖另一个(至少,不是在您希望的意义上)。

在您呈现的代码中,InteractorStyle::MyFunction是非虚拟的。因此,它不能覆盖或"实现"任何虚函数。

但是,即使您在那里添加了virtual关键字,InteractorStyle::MyFunction仍然不会在您的派生类PointSelector2D中作为PointSelector::MyFunction的实现。

为了作为实现,InteractorStyle::MyFunction必须定义在从PointSelector派生的类中。但是,如果您只是这样做,让InteractorStyle继承PointSelector,那么在其余代码不变的情况下,仍然不可能是PointSelector2D中的实现。更糟的是,它会带来歧义!

为什么?因为PointSelector2D随后包含两个PointSelector基类子对象,一个来自InteractorStyle(您添加了继承),另一个来自PointSelector的直接继承。

所以,如果你需要保持InteractorStyle2D显式继承PointSelector的代码,你想通过继承来实现,就像在Java中一样,那么& help;

解决方案是认识到PointSelector实际上是一个接口类,并实际上从它继承,这确保只有一个基类子对象:
// This class defines an "interface".
class PointSelector
{
public:
    virtual void myFunction() = 0;
};
// Derived virtually from the interface
class InteractorStyle
    : virtual public PointSelector
{
public:
    void myFunction(){}
};
class PointSelector2D
    : public virtual PointSelector
    , public InteractorStyle
{};

int main()
{
  PointSelector2D a;        // Ooh, it works! :-)
  a.myFunction();           // Yay! No ambiguity!
}

但是查找的歧义怎么办?好吧,虚拟派生也解决了这个问题,因为它带来了一个叫做支配的特殊规则,本质上编译器认识到,由于虚拟派生,PointSelector::myFunctionInteractorStyle::myFunction必须是相同的,并且前者是声明,而后者在派生类中必须是实现。这有点难以解释清楚,因为我从来没有找到关于它的标准条款,但至少在c++ 0x N3290中,您现在找到了"主导地位"。在索引中,参考§10.2/10和§10.2/11中的非规范性支配性例子。

但是,无论如何,这就是如何在c++中实现java风格的继承。

干杯,hth。