我应该如何实现一个纯虚方法与派生类型作为参数

How should I implement a pure virtual method with derived type as parameter?

本文关键字:派生 方法 参数 类型 一个 何实现 实现 我应该      更新时间:2023-10-16

我正在用c++编写程序,我来自Java,我遇到了一些麻烦。我想有一个基抽象类(java接口),它定义了派生类必须实现的一些方法。这个方法可以有派生类型作为参数,但在这里我发现了一个问题。如果我在基类中将它们定义为基类中的参数,编译器不会将派生类型的重新定义视为重写,派生类仍然是纯虚的。解决这种情况的正确方法是什么?谢谢!

我想你应该这样写:

template<class T>
class Interface {
  virtual void Method(T i) = 0;
};
class Implement : public Interface<Implement> {
  virtual void Method(Implement i) override {
  }
};

您应该做的是在派生类中创建一个以基类为参数的函数。您可以使用dynamic_cast来确保运行时类型确实是派生类(否则抛出异常)。正如chris在他的评论中提到的,逆变是"困难的"。

class Base
{
    public:
    virtual void fn(const Base &base)=0;
}
class Derived:public Base
{
     void fn(const Base &base)
     {
         const Derived *derived=dynamic_cast<const Derived *>(&base);
         if(derived!=nullptr)
         {//code for derived..
         }
     }
}

如果你真的必须得到你想要的,你应该选择CRTP。我想你真的不需要。如果你真的需要,Adrian的答案就是你要找的。

请记住,如果您选择CRTP,您将失去继承的一些好处。例如,您将无法创建基类指针列表(vector <Base *>)。当您使用基类(Base<Derived>)时,您需要选择派生类,这可能会破坏目的。

您正在尝试做的事情在Java中也不起作用。在Java中,返回类型可以是协变的,但不能是方法的参数。如果您考虑Liskov原则,这实际上是有意义的:如果您缩小派生类的契约,您将无法用派生对象替换基对象。

解决方案可能需要在设计层面。只是猜测,但这类问题涉及到您希望对类和参数类型进行分派的情况。如果是这种情况,请查看访问者模式。