无效的协变返回类型(参数也继承)

时间:2013-11-21 04:05:41

标签: c++ templates inheritance

我收到此错误 '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继承自州

类JumpState:public State

2 个答案:

答案 0 :(得分:2)

我认为代码中的意图是getNextinitsolveprint都在派生类型中被覆盖,但事实并非如此出于不同的原因。

init的情况下,由于没有参数,编译器会解释您希望在基类中使用相同的名称覆盖该函数。 C ++允许共变量类型(覆盖的返回类型可以是基类中函数返回的类型的派生类型)提供返回类型是指针< / em>或引用,但一个值。

solvedprint的情况下,派生类型中声明的函数覆盖在参数集中使用相同名称声明的函数不一样。 C ++支持协变返回类型,但是对于覆盖另一个的函数,参数必须相同。

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

此外,不管模板参数的关系是什么,不同的模板实例都是不相关的类型,因此在getNext的情况下,类型vector<State>vector<JumpState>不相关即使StateJumpState是继承,也会继承。

答案 1 :(得分:1)

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

virtual State& init();

会奏效。不幸的是,更大的问题是

virtual vector<State> getNext(State);

vector<JumpState> getNext(JumpState);

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

你实际上可能需要这个:

template <class State> class Puzzle { .. 

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