2014-10-02 105 views
0

我正在經歷從Java到C++的轉換,並試圖編寫一個簡單的程序。調用超類方法運算符==

有一個超Animal具有以下inteface:

class Animal 
{ 
public: 
    Animal(int a, std::string n); 

    bool operator==(Animal a); 
private: 
    int age; 
    std::string name; 
}; 

而且它的子類Dog

class Dog : public Animal 
{ 
public: 
    Dog(int a, std::string n, double w); 

    bool operator==(Dog d); 
private: 
    double weight; 

}; 

我的問題是關於狗的operator==方法,其中比較2只狗。

動物的operator==低於。

bool Animal::operator==(Animal a) //overriding of operator == 
{ 
return (age==a.age) && (name==a.name); 
} 

現在我想用Animal的方法編寫狗的版本。

就像我在Java中做到:

boolean equals(Dog d){ 
    return (super.equals(d)) && (this.name==d.name); 
} 

我需要的是(super.equals(d)) C++的等價物。如果它是一個正常名稱的方法,它會很容易(Animal :: equals(d)),但我不知道如何爲operator ==操作,它有不同的語法。

+2

使用標準符合簽名:布爾運算符==(const Animal&a)const;' – 2014-10-02 18:15:00

+0

你知道如何在父類中調用普通函數嗎?當你弄明白的時候,你只需要記住'operator =='只是一個普通的成員函數。 – 2014-10-02 18:16:06

+0

@crashmstr:因爲他說他已經知道如何使用'Animal :: equals(d)'了,所以不是這樣。 – 2014-10-02 18:16:49

回答

6

這其實非常容易:

return Animal::operator==(d) && name==d.name; 

之所以使用超類的名稱,而不是super的是,在C++中,你可以有多個超類,所以你必須要清楚你要哪一個。

或者,你可以通過使用它調用它的過載:

return ((Animal&)*this)==d && name==d.name; 

因爲在這種情況下,paramters到operator==將是一個Animal&Dog&,那麼它無法比擬Dog::operator==(Dog d),所以使用Animal::operator==(Animal a)代替。

注意:您的簽名非常不尋常。相反,使用其中的一個:

bool operator==(const Animal& a) const; 
friend bool operator==(const Animal& left, const Animal& right); 

這些不要讓動物的副本每次比較的時間,可以比較const動物。

+0

謝謝,我應該嘗試添加這樣的「運算符」,但我認爲它不會工作,因爲我通過做(object1 == object2)來調用方法。 – 2014-10-02 18:25:35

0

您可以使用詳細註釋呼叫話務員:

operator==(const Dog& dog) { return Animal::operator==(dog) && weight==dog.weight; } 
+0

'weight'是'double'類型,你確定你的代碼好嗎? – 2014-10-02 18:25:15

+0

@PiotrS。爲什麼不?它取決於實際值的來源,但如果它們基本上是不變的,並且來自人類的輸入,那麼測試就很好。 – 2014-10-02 18:26:54

+0

@JamesKanze:例如消除你提到的這種「依賴性」?讓他們改變? – 2014-10-02 18:28:57

0

你的Java equals的直接等同是:

bool Dog::operator==(Dog d) 
{ 
    return Animal::operator==(d) && weight == d.weight; 
} 

但我不知道這是你真正想要的。對於初學者, 你正在通過複製參數,這意味着你的 比較副本。特別是,當您撥打 Animal::operator==時,您將通過Animal部分 的Dog的副本,而不是完整的對象。班級類型通常是 通過引用傳遞;參考const如果你不想 修改它們。因此,在底部的簽名會是這樣 這樣的:

bool Animal::operator==(Animal const& other) const 
{ 
    // ... 
} 
Dog

而與此類似。此外,Dog 中的比較運算符可能需要Animal const&,而不是Dog const&。 (在 的Java,equals需要java.lang.Object,永遠。)這意味着 是你必須確認它是一個Dog

bool Dog::operator==(Animal const& other) const 
{ 
    return dynamic_cast<Dog const*>(&other) != nullptr 
     && Animal::operator==(other) 
     && weight == other.weight; 
} 

編輯:

正如指出的評論,雖然這解決了 即時語法問題的原始海報,它不是 真的是我們通常這樣做的方式。通常的解決辦法 是這樣的:

class Animal 
{ 
    // If Animal is actually an abstract class (usually the case 
    // in real code), this would be a pure virtual. 
    // Derived classes overriding this function are guaranteed 
    // that other is actually of the same type as they are, 
    // so they can just static_cast it to their type. 
    virtual bool doIsEqual(Animal const& other) const 
    { 
     return true; 
    } 
public: 
    bool isEqual(Animal const& other) 
    { 
     return typeid(*this) == typeid(other) 
      && // ... his local conditions... 
      && doIsEqual(other); 
    } 
}; 

bool operator==(Animal const& lhs, Animal const& rhs) 
{ 
    return lhs.isEqual(rhs); 
} 

bool operator!=(Animal const& lhs, Animal const& rhs) 
{ 
    return !lhs.isEqual(rhs); 
} 

operator==實施和operator!=實際上可以 通過適當的類模板,它 避免了一些樣板的繼承來完成,如果你有很多的類 其中必須支持==和其他。

+0

如果您擁有* concrete *類的子類,則您的比較方法需要進行一些調整。試試'動物(1,「筷子」);狗b(1,「筷子」,30); (a == b)==(b == a)'。 – 2014-10-02 18:43:23

+0

@ n.m。是。在實踐中,我會在'Animal'中使用一個虛擬的'isEqual'函數,其中包含自由函數'operator =='和'operator!=',這個函數僅用於'Animal'。 (但是,我仍然懷疑繼承具體類,除非我使用模板方法模式,我認爲OP實際上只是創建了一個人爲的例子來演示他提出的語法問題;這種類型的層次結構並沒有實現, t出現在編寫良好的代碼中。) – 2014-10-03 09:23:33

+0

比較typeid有它自己的陷阱。假設有人發佈具有各種形狀類的幾何圖形庫,並且其他人將其擴展到繪圖庫,添加顏色和其他繪圖樣式。現在,彩色形狀永遠不會與普通的無色形狀相同。但幾何圖書館不關心顏色,它需要幾何平等。同樣,不同顏色的形狀總是不相等的,這對於繪製操作來說是可以的,但會破壞依賴於幾何比較的幾何操作。 TL; DR == ==在層次結構中是危險的,但是你看它。 – 2014-10-03 09:43:55