2013-04-23 33 views
2

我最近開始學習C++(沒有事先編程知識)。我已經使用了「跳入C++」這本書,作者Alex Allain,我發現它非常有用!然而,我已經達到了類,繼承和多態的章節,雖然我明白了大部分內容,但我無法將我的頭圍繞這個問題。排序功能,需要一個接口類的指針向量

在這本書中,我要求解決以下問題:

實現定義的方法排序函數,它指針的載體接口類,可比, ,比較(可比&其他),如果對象是 ,則返回0;如果對象大於其他,則返回1;如果對象小於其他,則返回-1。創建一個實現此接口的類 ,創建幾個實例並對它們進行排序。如果您正在尋找 創作內容的一些靈感 - 嘗試一個具有名稱和 分數的HighScoreElement類,並進行排序,以便首要分數排在前面,但如果兩個分數相同,則排序 下一個按名字。

我創建可比類和高分:

class Comparable { 

public: 

    virtual int compare(Comparable& other)=0; 

}; 



class HighScore : public Comparable { 

public: 
    HighScore(int, std::string); 

    virtual int compare(Comparable& other); 


private: 
    int highscore; 
    std::string name; 

}; 

如果我試圖覆蓋在高分繼承的功能,我不能夠進行比較,比如INT高分,與INT (比較&其他)的高分,因爲我無法訪問other.highscore。下面的例子:

int HighScore::compare(Comparable& other){ 

    if (highscore == other.highscore) { 
     return 0; 
    } 

    //... 
} 

我想我可以在虛擬方法可能更改爲類似:

int HighScore::compare(HighScore& other){ 

    if (highscore == other.highscore) { 
     return 0; 
    } 

    //... 
} 

因爲這將使我訪問other.highscore(我希望我會因爲工作HighScore也可以被認爲是一個可比較的,但唉,沒有這樣的運氣,我應該怎麼做,我litterally沒有線索如何繼續,我將不勝感激任何幫助,我可以得到感謝:)

回答

1

事實上,試圖根據兩個或多個對象的運行時類型來選擇行爲在C++等單一調度語言中有點難以理解。

最簡單的解決方案是使用RTTI來確定是否其他對象有一個類型與我們相媲美:

int HighScore::compare(Comparable& other){ 

    int other_highscore = dynamic_cast<HighScore&>(other).highscore; 

    if (highscore == other_highscore) { 
     return 0; 
    } 

    //... 
} 

這將拋出一個異常,如果該類型沒有可比性,這可能是最好的,你可以做。

或者,您可以實現一個雙調度機制(如「訪問者模式」),涉及兩個虛函數。我會讓你自己研究一下,因爲一個例子會囉嗦,而不是特別鼓舞人心。

希望你很快會學會如何使用編譯時泛型而不是運行時抽象接口來實現這一點,這在C++中更具慣用性。如果這本書沒有教你這個,把它扔掉,取而代之的是these

+0

如果參考文獻中的dynamic_cast失敗,則會引發異常。 '9指針類型失敗轉換的值是所需結果類型的空指針值。一個失敗的 強制轉換爲引用類型會拋出一個類型爲與匹配 std :: bad_cast(18.7.2)類型的處理函數(15.3)的異常(15.1)。' – alexrider 2013-04-23 18:50:18

+0

@alexrider:的確,這就是我剛纔所說的這個例子。你還會如何處理比較兩種無法比較的類型? – 2013-04-23 18:51:16

+0

哦,很抱歉誤讀了。 – alexrider 2013-04-23 18:51:49

0

你可以寫一個pulic獲得功能得分

class Comparable { 
public: 
    int get_score() const = 0; 
    // 
} 

class HighScore : public Comparable { 
public: 
    int get_score() const { return highscore; } 

然後用它來比較。

int HighScore::compare(Comparable& other){ 

    if (highscore == other.get_score()) { 
          ^^^^^^^^^^^ 
     return 0; 
    } 

    //... 
} 

但因爲只有派生類highscore成員你應該改變你通過比較什麼。

int HighScore::compare(HighScore& other) 

或將highscore成員移動到基類。無論男性對你有意義。

+0

你的意思是在'Comparable'類中添加'get_score()'函數(因爲這是'other'的所有靜態類型信息)?那些想要比較身高,體重或大象數量的其他派生類呢? 「Comparable」應該包含所有這些東西的getters嗎? – 2013-04-23 18:37:57

+0

@MikeSeymour哦。對。 – stardust 2013-04-23 18:39:30

+0

@MikeSeymour我在那裏添加它,因爲高分實際上並不是基礎的成員。所以我忽略了他通過了類比。不過,我認爲他應該通過** HighScore **類而不是類比。 – stardust 2013-04-23 18:43:14

0

我建議選擇另一本書的主題。由於這個練習似乎很模糊,並且不能很好地理解多態性。棘手的部分是,當你在compare方法中得到Comparable時,你不知道如果它是HighScore或其他派生類。如果您嘗試比較的課程不是HighScore的實例,那麼等於越少越好的術語沒有任何意義。因此沒有辦法正確解決這個問題。您當然可以使用dynamic_cast來檢查它是否是HighScore,但如果它不是沒有好的答案,如果它更大,更小或等於非HighScore的東西。
想象一下存在像class Color : public Comparable {這樣的東西。如果您將Color與HighScore進行比較,您應該返回哪些內容?藍色大於10,或者黃色小於15,紅色等於什麼?

+0

我會盡力找到關於這個問題的其他來源,謝謝你的幫助。 – 2013-04-23 18:48:13