2013-06-25 31 views
1

我目前正在實現C++標籤支持類。不過,我有點困惑的不同的行爲重載運營商的isEqual和方法:C++運算符與方法重載及其不同的行爲

class Lbl 
{ 
public: 
    virtual bool operator == (const Lbl* l) const = 0; 
    virtual bool isEqual (const Lbl* l) const = 0; 
}; 

class SubLbl : public Lbl 
{ 
public: 
    SubLbl(){} 

    bool operator == (const Lbl* l) const {return true;} 
    bool isEqual (const Lbl* l) const {return true;} 
}; 

int main(int argc, char** argv) { 
    SubLbl* l1 = new SubLbl(); 
    SubLbl* l2 = new SubLbl(); 

    cout << (l1 == l2) << endl; 
    cout << (l1->isEqual(l2)) << endl; 
    return 0; 
} 

輸出:

0 
1 

這是爲什麼?我該如何改變這個以使操作符重載?爲什麼我必須繼承「public」以使「isEqual」方法可訪問?或者,這僅僅是我迄今爲止還沒有使用(並且不知道)的模板的典型情況?

我正在做的是實現不同的SubLbl類來支持我可以放在對象上的不同類型的標籤。所有(SubLbl類)都從Lbl類繼承,並且應該由於它們自己的相等定義而重載相等運算符(int比較不同於兩個複雜對象的比較,甚至不同於雙重比較)。後來(在程序中)我不想知道我目前正在查看哪種子標籤,我只是想知道它們是否平等。

回答

1

這一個:

l1 == l2 

是比較指針。如果l1l2的地址相同,這將是真實的。

這一個

l1->isEqual(l2) 

正在執行一個調用返回true的成員函數。

+0

值得注意的是'* L1 == * l2' *將*調用重載運算符。 –

+0

@AlexShesterov我不這麼認爲:操作符期望一個指針,調用'(* l1 == l2)'會做,我不認爲這是期望的行爲。 – Antonio

+0

@Antonio:哦......對......我沒有注意到簽名中的'*'(代替了通常的'&')... –

1

我不得不說,閱讀更好,這是一個非常棘手的答案,因爲你正在談論繼承和超載運算符。

我的猜測是,如果你不知道它們是完全相同的類,那麼你不應該將對象與運算符==進行比較。我的事情,你應該只定義,內SubLbl:

bool operator == (const SubLbl& l) const {return _something_;} 

注意我把類型的對象SubLbl作爲參數。而且我會避免在Lbl中定義一個虛擬的operator==,特別是如果是虛擬的。 另一方面,函數isEqual也可以。

你可以找到一些靈感不同的解決方案在這裏:Making operator<< virtual?

這是我的老答案

在第一種情況下,你是不是叫你定義的操作符,但你檢查是否2個指針指向相同的對象,或更好的是,具有相同的值。

要打電話給你的運營商,你就應該把:

cout << (*l1 == l2) << endl; 

但是你定義的操作符的方式並不值得推薦。你應該,例如,定義:

bool operator == (const Lbl& l) const {return _something_;} 

,並呼籲

cout << (*l1 == *l2) << endl; 
+0

感謝您的回答。事實上,基本的運算符==函數檢查類是否相同,並在後一種情況下返回false。如果爲true,則傳入的對象將進行類型轉換,並調用特定於類型的相等運算符方法(如您所建議的)。 –