2013-11-21 15 views
0

我得到這個錯誤 '虛擬JumpState Jump_peg :: init()'的無效協變返回類型我已經做了這個 你能提出什麼問題嗎?無效covariant返回類型(參數也繼承)

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:公國

+0

向前聲明'JumpState'前'Jump_peg'應該解決的問題。 – billz

+0

@billz:沒有。這沒有幫助。 –

回答

1

當您返回指針或引用,但不返回類對象時,Covariant返回類型工作。所以

virtual State& init(); 

會工作。不幸的是,更大的問題是

virtual vector<State> getNext(State); 

vector<JumpState> getNext(JumpState); 

是完全不相關的功能。後者不會覆蓋前者。對於接受State的所有其他功能對也是如此。要覆蓋,參數類型必須相同。

實際上,你可能會需要這樣的:

template <class State> class Puzzle { .. 

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

我想象中的代碼的意圖是getNextinitsolveprint都在覆蓋派生類型,但不是由於不同的原因。

init的情況下,由於沒有參數,編譯器會解釋您想在基礎中用相同名稱覆蓋函數。 C++允許用於共變體類型(置換器的返回類型可以是由函數在基本返回的類型的派生類型)提供,返回類型或者是指針參考,但不是的一個值。

solvedprint在派生類型中聲明的函數的情況下做不重寫與基座作爲設定的參數相同的名稱聲明的功能是不一樣的。 C++支持協變返回類型,但參數必須與函數相同才能重寫另一個類型。

即使參數允許某些變化,它也必須是反方差,而不是協方差,因爲協方差會縮小派生類型中函數的合約:基類型將採用任何State,但派生類型只能採取JumpState。派生類型將不能替代基礎,從而打破了Liskov替代原則。

而且,不同的模板實例是無關的類型,不管是什麼的模板參數的關係,所以在getNext的情況下,類型vector<State>vector<JumpState>沒有被繼承即使StateJumpState是相關的。