我应该如何使用派生类型作为参数实现纯虚方法?

时间:2015-09-26 16:26:00

标签: c++ oop inheritance

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

3 个答案:

答案 0 :(得分:3)

我想你想写这样的东西:

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

class Implement : public Interface<Implement> {
  virtual void Method(Implement i) override {

  }
};

这称为CRTP

答案 1 :(得分:0)

这里你应该做的是在派生类中创建一个以基类为参数的函数。您可以使用dynamic_cast来确保运行时类型确实是派生类(否则抛出异常)。正如克里斯在评论中提到的那样,反变数就是&#34;很难&#34;。

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。我怀疑你真的不需要。如果你真的需要它,阿德里安的答案就是你正在寻找的。

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

答案 2 :(得分:0)

你要做的事情也不适用于Java。在Java中,返回类型可以是协变的,但不是方法的参数。如果考虑Liskov原则,那实际上是有意义的:如果缩小派生类的合约,则无法用派生对象替换基础对象。

解决方案可能需要在设计层面上。只是猜测,但是这种问题与您希望在类上以及参数类型上发送调度的情况有关。如果是这种情况,请查看Visitor pattern.