2011-09-30 73 views
4

我有一個覆蓋+運算符和一個子類'B'的類'A'。C++如何繼承返回特定類型的運算符

我要繼承「A的+操作而不是返回A型我想返回類型B.

我怎麼能去這樣做?我嘗試從B調用父操作符並將結果投射到A對象,但它不會讓我將父項投射給子女

我的+運算符能否以某種方式返回通用的'A'指針?

+0

你能提供+運營商的簽名? –

+0

[C++:error C2440:''可能重複:無法從'A '轉換爲''B '](http://stackoverflow.com/questions/7614313/cerror-c2440- function-style-cast-can-convert-from-atype-to-bty) –

回答

2

它可能 - 沒有技術原因它不能 - 它只是在使用操作符時違反了一些期望。因此,如果這是你自己的代碼,去爲它,但如果它要讀取或由其他人使用,我會重新考慮的原因如下:

  1. 預期的行爲是運營商如+=*=回報對修改該對象後被調用的對象的引用。像+*這樣的運算符會返回一個新對象(它們非常必要,因爲暗示它們被調用的對象沒有更改)。他們不返回一個指針到一個新的對象,因爲:
  2. 沒有人期望他們,所以他們不會認爲他們delete從運營商,這將導致內存泄漏回來的對象,並且:
  3. 你不能鏈接返回指針的操作符;像MyClass a = b + c + d;這樣的表達式將不起作用,因爲返回類型(MyClass*)與您需要傳遞給運算符的參數類型(可能爲const MyClass&)不匹配。
  4. 將一個參考返回給一個新的對象可以讓你在#3處工作,並且仍然支持多態,但是你仍然堅持#2,而且這是更糟糕的一對。這同樣適用於重載操作符以獲取指針或引用。

最終,只要做任何事情都可以讓任何人使用代碼變得簡單 - 如果只是你,你可以做任何你想做的事情。只是要小心,如果它會落入別人的手中,因爲他們作出假設。

希望這會有所幫助!

編輯:返回到一個新的對象的引用的一個例子:

A& A::operator + (const A& other) const 
{ 
    A* temp = new A(); // <- This is why it's a potential memory leak 
    /* Do some stuff */ 
    return *temp; 
} 

但是,有過一點時間思考這個問題,我會提出替代:定義=操作對於以A爲參數的B來說。然後,你可以做這樣的事情:

B b1; 
B b2; 
B b3 = b1 + b2; 

而且它不會有問題的是b1 + b2返回A,因爲它是在=期間轉換回A B。如果這適合你,我會推薦它高於任何其他方法,因爲它可以讓所有的操作員都預期行爲。

+0

你可以給一些示例代碼來說明如何返回泛型引用嗎? – James

+0

@James - 爲你提供一些示例代碼。另一個建議,我會推薦我以前的任何想法。乾杯! –

+0

另一種選擇是返回隱藏指針類型成員變量中多態性的類型。這種類型然後多元化地起作用,但可以通過價值返回。 'auto_ptr' /'unique_ptr' /'scoped_ptr' /'shared_ptr'是接近的,但它們試圖像指針一樣行事。自定義智能指針可以像對象一樣工作。 –

1

解決此問題的最簡單方法是按照operator+=實施operator+。所以大致爲:

A::operator+=(const A& right) { /* stuff */ } 
B::operator+=(const B& right) { static_cast<A&>(*this) += right; /* stuff */ } 
operator+(B left, const B& right) { return B += right; } 
+0

這很有趣,但是可以通過其他方式來完成嗎?通過'+'來實現'+ ='。當前版本具有意想不到的屬性,即「left + right」更改「left」值。如果不是那樣的話,我會比我的建議更好... –

+0

@XavierHolt:'left'是一個副本。因此,調用者永遠不會看到更改,這一點並不重要。 –

+0

@贊 - 啊哈!錯過了。那麼這很聰明。 –

2

我經常看到它在下列方式進行: