是否可以在子类中重载纯虚函数的实现?

问题描述 投票:0回答:2

我正在开发一个项目,其中有一个名为

MSTAlgorithm
(最小生成树算法)的基类。称为
PrimsAlgorithm
KruskalsAlgorithm
的两个类公开派生自该基类。我认为这是正确的,因为这两种算法与基类具有“is-a”关系 - 即它们都是 MST 算法,只是实现略有不同。通过在基类中编写两种算法通用的方法,我不必重写两种算法通用的代码,并且我可以使用指向基类的指针,例如 std::unique_ptr<MSTAlgorithm> algorithm = std::make_unique<KruskalsAlgorithm>()
std::unique_ptr<MSTAlgorithm> algorithm = std::make_unique<PrimsALgorithm>()
我在我的基类上定义了以下纯虚拟方法(表示它必须由从此基类派生的任何类实现):

class MSTAlgorithm { public: virtual std::queue<Edge> findMST(Node& startingNode) = 0; }

我试图弄清楚是否可以在具有不同参数的派生类中实现
findMST

,即重载此函数。由于算法工作方式的本质,Kruskals 不需要起始节点,而 Prims 则需要。是否有可能以某种方式“重载”纯虚函数实现?

下面的代码显示了我的意图,但无法编译,因为编译器不希望在 

findMST

上为

PrimsAlgorithm
传递任何参数:
class KruskalsAlgorithm : public MSTAlgorithm {
  public:  
    std::queue<Edge> findMST();
}

class PrimsAlgorithm : public MSTAlgorithm {
  public:
    std::queue<Edge> findMST(Node& startingNode);
}

c++ oop overriding pure-virtual
2个回答
3
投票
KruskalsAlgorithm

的实例,您将看到您没有覆盖

findMST
,您已经声明了另一个成员。因为它继承自
MSTAlgorithm
但不提供
findMST(Node&)
,因此您将无法创建实例。
为了能够多态地使用它,参数必须匹配。您将有一个类似的呼叫站点

std::unique_ptr<MSTAlgorithm> algorithm; Node node; algorithm->findMST(node);

即总会有一个节点通过。最简单的方法是在 
Node&

中获取

KruskalsAlgorithm
参数,并且不对其执行任何操作。
我还建议您使用关键字 

override

来表示您希望覆盖基类中的虚拟成员的成员函数,这样当它们不匹配时您就会收到警告,就像这里一样。

class KruskalsAlgorithm : public MSTAlgorithm {
  public:  
    std::queue<Edge> findMST(Node&) override;// Unnamed parameter because unused
}



0
投票

如果无法更新父类,则可以解决新子类中出现额外意外参数的问题:创建一个额外的方法来接收并记住额外的参数。在调用站点,分两个阶段完成工作 - 传递新参数,然后调用常规重写方法。

您甚至可以创建一个执行这两种操作的非虚拟方法,并为其指定与虚拟方法相同的名称,但这不会使其以多态方式运行。

© www.soinside.com 2019 - 2024. All rights reserved.