2013-07-19 102 views
3

我是C++的新手,我正在編寫一個簡單的代碼來比較一個名爲Comparable的父類的子類的兩個對象。我想每個子類有它自己實現一個比較基礎上,他們持有的數據對象的方法,所以我用虛擬關鍵字:虛擬功能實現C++不工作

class Comparable { 
public: 
virtual int compare(Comparable *other); 
    }; 

例如,我的子類HighScoreElement將有自己的執行比較是的會將對象的分數與另一個HighScoreElement的分數進行比較。

這裏是我的子類HighScoreElement:

class HighScoreElement: public Comparable { 
     public: 
virtual int compare(Comparable *other); 
HighScoreElement(string user_name, int user_score); // A constructor 
     private: 
int score; 
string name; 

}; 

但在我HighScoreElement比較實施,我第一次嘗試檢查當前對象的數據是一樣的其他數據。但是由於指向其他類的指針是Comparable類而不是HighScoreElement,因此即使HighScoreElement是Comparable的子類,我也無法在代碼中引用other->分數。

這是迄今爲止全碼:

#include <iostream> 
using namespace std; 

class Comparable { 
public: 
virtual int compare(Comparable *other); 
    }; 

class HighScoreElement: public Comparable { 
public: 
    virtual int compare(Comparable *other); 
    HighScoreElement(int user_score, string user_name); 
private: 
    string name; 
    int score; 
}; 

HighScoreElement::HighScoreElement(int user_score, string user_name) { 
name = user_name; 
score = user_score; 
} 



int HighScoreElement::compare(Comparable *other) { 
if (this->score == other->score) { // Compiler error right here, other->score is invalid. 
    // Code to do the comparing if two scores are equal... 
} 
} 

我立即得到一個編譯錯誤,當我寫這篇文章的代碼:

if (this->score == other->score) 

因爲其他沒有數據稱爲比分,但其子類HighScoreElement的確如此。如何修復我的函數實現,以便可以引用「其他」的數據?我知道我的問題可能聽起來含糊不清,但任何幫助將不勝感激!

+0

一個簡單的解決辦法是使用'的dynamic_cast (其他)',它返回'nullptr'('0')的情況下,'other'不指向HighScoreElement'的'的實例(或從中得出)。不過,可能有更好的設計,但不包括'dynamic_cast'。 – dyp

+2

沒有什麼個人的,但這個代碼是醜陋的。看起來像Comparable作爲接口的某種java風格的c + +代碼?我的心碎了。 – kvv

+0

@kw當我開始使用C++時,我的代碼非常糟糕。=)學習過程是一條泥濘的道路。隨着時間的推移,人們的代碼質量會提高。 –

回答

1

您可以在基類中實現一個虛擬函數GetScore(),可能是pure virtual,並使用該函數代替比較函數中的字段分數。使其成爲一種常量方法。在另一方面,比較可能是在基類中實現的方法,使用this->GetScore()other->GetScore()

代碼存根:

class A { 
    virtual int getScore() const = 0; 
    inline bool compare(const A* in) {return (in && this->getScore() == in->getScore());} 
    //return false also if "in" is set to NULL 
    } 


class B : public A { 
    int score; 
    inline int getScore() const {return score;} 
    } 
+0

感謝您的輸入!現在我可以看到我應該如何實施它。 – ra1nmaster

+0

@ Ra1nMaster歡迎您!如果您願意,您可以決定[接受其中一個答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – Antonio

+0

我重寫了我的代碼,以便其他人可以採用一個純粹的虛擬getScore函數,它將返回適當的分數值。 – ra1nmaster

-1

你確定這不是

比較(可比其他

If(this-> score == other.score

+0

「Comparable」不包含名爲'score'的成員,並且您的建議會對從「Comparable」派生的所有傳入對象進行切片。 – dyp

+0

嗯,我認爲這裏有些困惑。 OP可能會混淆實現Comparable接口和使用Comparable作爲傳遞的類型。 –

0

您可以使用「dynamic_cast」強制傳遞給HighScoreElement :: compare的指針(它在失敗時拋出bad_cast異常)。

int HighScoreElement::compare(Comparable *other) { 
HighScoreElement *h = NULL; 
try 
{ 
    ptr = dynamic_cast<HighScoreElement *>(other); 
} 
catch(std::bad_cast const &) 
{ 
    // Handle the bad cast... 
} 
if (this->score == ptr->score) { 
// Code to do the comparing if two scores are equal... 
} 
} 
+0

[expr.dynamic.cast]/9「指針類型失敗轉換的值是所需結果類型的空指針值。失敗 強制轉換爲引用類型拋出異常[0123]」 – dyp

+0

@DyP :是的,謝謝你的澄清。 – SeaBass

+0

@SeaBass你的回答是錯誤的。 – BlackMamba

0

如果您準備接受空指針,則可以使用動態轉換。當您比較HighScoreElement指針以避免不必要的轉換時,可以對案例負載過重。

#include <iostream> 
using namespace std; 

class Comparable { 
public: 
    virtual int compare(Comparable *other) = 0; // made pure virtual to compile without definition 
}; 

class HighScoreElement: public Comparable { 
public: 
    virtual int compare(Comparable *other); 
    int compare(HighScoreElement *other); // comparing to a HighScoreElement ptr, no need to dynamic cast 
    HighScoreElement(int user_score, string user_name); 
private: 
    string name; 
    int score; 
}; 

HighScoreElement::HighScoreElement(int user_score, string user_name) { 
    name = user_name; 
    score = user_score; 
} 

int HighScoreElement::compare(Comparable *other) { 
    HighScoreElement * pHSE = dynamic_cast<HighScoreElement*>(other); 
    if (pHSE) { 
    return compare(pHSE); 
    } else { 
    return -1; // or however you want to handle compare to non HighScoreElement 
    } 
} 

int HighScoreElement::compare(HighScoreElement *other) { 
    if (this->score == other->score) { 
    ; 
    } 
} 
+0

@DyP謝謝。似乎我從來沒有100%的權利。更正 –

+1

沒有人會獲得所有東西總是100%正確;) – dyp

+0

請注意,您還應該更改代碼,它當前包含可能的訪問衝突(因爲沒有例外,'other-> score'可能在nullptr上運行)。派遣很好,如果'dynamic_cast'返回'0',那麼這些對象是不相等的。但是請注意'other'可能來自'HighScoreElement',因此只有檢查'score'可能不夠。 – dyp