【问题标题】:invalid covariant return type ( parameters also inherited )无效的协变返回类型(参数也被继承)
【发布时间】:2013-11-21 04:05:40
【问题描述】:

我收到此错误 “virtual JumpState Jump_peg::init()”的协变返回类型无效 我已经做到了 你能提出什么问题吗?

class Puzzle{

    public:
        virtual vector<State> getNext(State) = 0;
        virtual State init() = 0;
        virtual bool solved(State) = 0; 
        virtual void print(State) = 0;   
};

class Jump_peg:public Puzzle{

    private: 
    int size;
    public:
        vector<JumpState> getNext(JumpState);
        JumpState init();
        bool solved(JumpState); 
        void print(JumpState);
        void jump(JumpState,int,int,vector<JumpState>&);
};

在我的代码中 jumpstate 继承自 state

类 JumpState:公共状态

【问题讨论】:

  • Jump_peg 之前声明JumpState 应该可以解决问题。
  • @billz:不。那没有用。

标签: c++ templates inheritance


【解决方案1】:

我想代码中的意图是 getNextinitsolveprint 都在派生类型中被覆盖,但由于不同的原因,情况并非如此。

init 的情况下,由于没有参数,编译器会解释您要在基中使用相同名称覆盖函数。 C++ 允许协变类型(覆盖器的返回类型可以是基函数返回的类型的派生类型)假设返回类型是 指针 或 reference,但 不是 值。

solvedprint 的情况下,在派生类型中声明的函数不会覆盖在基类中以相同名称声明的函数,因为参数集不同. C++ 支持协变返回类型,但函数的参数必须相同才能覆盖另一个函数。

即使允许参数有一些变化,它也必须是反方差,而不是协方差,因为协方差会缩小派生类型中函数的契约:基本类型将采用 any State,但派生类型只能采用 JumpState。派生类型不能替代基类,这违反了 Liskov 替换原则。

此外,不同的模板实例化是不相关的类型,无论模板参数的关系如何,所以在getNext的情况下,vector&lt;State&gt;vector&lt;JumpState&gt;类型即使State也没有继承关系和JumpState 是。

【讨论】:

    【解决方案2】:

    协变返回类型在您返回指针或引用时起作用,但在类对象中不起作用。所以

    virtual State& init();
    

    会起作用的。不幸的是,更大的问题是

    virtual vector<State> getNext(State);
    

    vector<JumpState> getNext(JumpState);
    

    是完全不相关的函数。后者不会覆盖前者。对于接受State 的所有其他函数对也是如此。要覆盖,参数类型必须相同。

    你实际上可能需要这个:

    template <class State> class Puzzle { .. 
    
    class Jump_peg : public Puzzle<JumpState> { ...
    

    【讨论】:

      猜你喜欢
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多