2011-08-08 14 views
0

我有一個類的層次結構,我必須重載operator+operator-,以便它產生一個像這樣的新類型。在子類上重載

Animal * pg = new Pigeon(); 
Animal * pgone = new Pigeon(); 

Animal * babypigeon = *pgone + *pg; 

Animal是基類型和Pigeon是派生型。我想知道是否應該重載派生類型的操作符,還是需要重載基類型的操作符?

假設所有派生類型都將使用基指針創建。

+1

你的意思是'Animal * babypigeon = * pgone + * pg;'? – iammilind

+0

是的,這就是我的意思 –

+5

我真的希望這是作業(在這種情況下,請添加相應的標籤)。我永遠不會寫'operator +'在哪裏寫'have_sex'函數。 –

回答

3

您的邏輯已關閉,您的程序將無法完成您期望的操作。你在那裏添加指針。 +運算符將不會被調用。

你需要像

babypigeon = (*pgone) + (*pg); 

在這種情況下,要添加兩種動物。所以你的+操作符必須在Animal類中重載。

解決這個問題的方法是從+運算符調用一些虛擬方法,並在那裏使用邏輯。

編輯:

class Animal{ 
//.... 
    virtual Animal plusLogic(const Animal& otherAnimal) const; 
    Animal operator + (const Animal& otherAnimal) const 
    { 
     return this->plusLogic(otherAnimal); 
    } 
} 

class Pigeon : public Animal{ 
//..... 
    virtual Animal plusLogic(const Animal& otheAnimal) const; 
} 
Animal Pigeon::plusLogic (const Animal& otherAnimal) const 
{ 
    //logic heree 
} 

這樣,主叫+運算上的動物的類型是鴿子的將調用函數plusLogic類鴿子(因爲它是虛擬的)。

+0

你能告訴我一個你建議的虛擬方法解決方案的簡單例子嗎? –

+0

我編輯了我的答案,希望它有幫助。 –

+0

我知道這是一個共同的想法來規避這種設置產生的問題,但它沒有多大意義。首先,爲什麼運營商委託虛擬功能,而不是自己虛擬?我能看到的唯一原因是將多態性與運算符重載混合在一起(明智)害羞,但將其隱藏在代理團隊後面並不會幫助解決底層問題。此外,這仍然不能回答你應該如何實現'Pigeon :: plusLogic()',這是一個問題的核心問題。做託尼想要的東西是不好的,應該避免。看到我的答案。 – sbi

2

你不能這樣做 - pgonepg是指針類型,不能爲它們重載運算符。你就必須有

Animal* baby = *pgone + *pg; 

在這種情況下,你需要一個雙調度系統覆蓋所有的情況下,我也希望你從來不想使用這些類型的值。我希望你也沒有太多派生類型,因爲它可能會很快變得討厭。

+0

我編輯了我的問題,以便它不是指針類型,而是類型本身,這就是我正在尋找的。 –

1
  • 你可能不超載的指針類型的運營商,所以你的代碼不應該編譯(編輯:這個問題已被修改和不應編譯部分不再有效),

    • 看到上面的限制,
    • 多態類型,你經常需要多個DIST:非多態類型一般運算符重載最好的工作補丁能夠做一些事情meaningfull
    • 返回一個多態值有其自身的問題(誰是所有者,如果一個需要分配的東西),增加了運營商驅動(a+b+c
    • 進行組合潛在的事實解決方案是信/ ENVELOPPE成語
+0

爲什麼不應該編譯代碼? –

+0

當然,它編譯,指針總是可以添加,但他改變了他的問題代碼。 –

+0

@Luchian,因爲在OP編輯他的問題之前,有一個語法錯誤。 – AProgrammer

1

我看到這種方法非常的幾個基本問​​題:

  1. 沒有universall (真的,用*而不是+?表示更好嗎?),所以這個明確的違反了first basic rule of operator overloading
    雖然@亞歷山大開了一個玩笑,但他在評論中確實有一個好點:寧可使用這個有名的功能

  2. 運算符重載是東西是非常適合值類型,並不適合用於多態類型。配對任何兩隻動物都沒有任何意義。
    您不能一般地指定結果的(動態)類型,因爲您必須爲每個排列創建一個新類型,從而創建新的可能排列,從而導致類型的無限擴展。 (並且如果你嘗試使用動物保護聯盟,他們可能會非常惱人)。

  3. 您的示例中使用的運算符通過引用獲取兩個對象,但必須返回一個指向動態分配對象的指針。這不僅聽起來非常錯誤,它也是。
    對於初學者來說:現在你不能鏈添加了(pg1 + pg2 + pg3,因爲另外的結果是相同類型的操作數不是這是非常反直覺和違反the second basic rule of operator overloading
    ,我不會。甚至像碰誰擁有返回的對象問題,誰負責清理起來

所以這個結果是:只是不這樣做。而我並不覺得奇怪,因爲多年來我已經瞭解到,如果您嘗試在此類設置中應用運算符重載,通常會產生這種結果。