簡體   English   中英

派生類中的C ++重載方法

[英]c++ overloaded method in derived class

我有以下問題:

假設基類A具有方法:

A& operator+(A& a) {...}

我也有一個派生類B重載(或至少應該這樣)此方法:

A& operator+(B& b) {...}

問題是,如果我想調用類似的東西:b + a(其中b為B類型,a為A類型),則會出現編譯錯誤。 (錯誤C2679:二進制'+':未找到采用'A'類型的右側操作數的運算符(或沒有可接受的轉換))。

那不應該調用基類方法嗎? (看起來它覆蓋了該方法。)如果沒有,為什么? 有沒有辦法解決此問題(不要告訴我用A&重載B中的方法)

抱歉,我沒有提供格式化文本的示例,但是我不知道如何格式化文本。

提前致謝!

PS Im使用Visual Studio 2010 Beta。

問題稱為隱藏 -派生類中的成員函數隱藏基類中具有相同名稱的函數。 在這種情況下,您將無法訪問A :: operator +(A&),因為它已被B :: operator +隱藏。 解決此問題的方法是定義B :: operator +(A&),並可能讓它調用基類函數。

編輯: C ++ FAQ Lite中有一節專門介紹此問題,並提供了另一種可能的解決方案,即using關鍵字。

問題在於您正在定義成員運算符,因此當稱為b + a它會導致b.operator+( a )不存在。

公認的做法是定義自由運算符 ,它們自己將在參數上調用[虛擬]成員。

編輯:

我正在談論的標准示例是為輸出流調整類層次結構:

 class base { public: virtual ~base(); virtual void print( std::ostream& ) const; }; std::ostream& operator<<( std::ostream& out, const base& b ) { b.print( out ); return out; } 

這實際上不適用於數學運算,因為您想返回[const]值而不是引用,即避免像a + b = c;這樣a + b = c;廢話a + b = c;

例如,定義了實數和復數的加法,但是結果是產生復數,因此您不能從real派生complex 另一種方式-也許。 但是,您仍然想定義確切的操作界面:

 const real operator+( const real&, const real& ); const complex operator+( const complex&, const complex& ); 

希望這能給您足夠的機會來重新考慮您的設計:)

不,它不會調用基類函數。 B類有一個operator+ ,它沒有采用正確的參數,故事的結尾。

您可以將operator+定義為自由函數,而不是任何類。 如果需要訪問私人數據,也許是個朋友:

A operator+(const A &lhs, const A &rhs) { ... }
B operator+(const B &lhs, const B &rhs) { ... }

然后,b + a和a + b都將調用第一個運算符。 b + b將調用第二個。

另外,您可以通過將其放入類B中來“取消隱藏”基類實現:

using A::operator+;

不過,最好不要這么做。 大多數運算符可以作為自由函數更好地工作,因為這樣您就可以在兩個操作數上進行自動轉換。 C ++永遠不會在成員函數調用的LHS上執行轉換。

順便說一句,operator +幾乎肯定應該按值返回,而不是按引用返回,因為一旦函數返回,自動(堆棧)變量將不復存在。 因此,需要向調用方傳遞結果的副本,而不是對它的引用。 因此,operator +和繼承不是很好的結合,盡管只要調用者知道他們在做什么,它就可以工作。

我想到了幾件事。 首先,您通常希望使運算符+為“虛擬”。 然后,由於協方差,派生的運算符+對B的引用將被覆蓋,而不是隱藏基類實現,這就是這里發生的情況。

話雖如此,我懷疑(但不能肯定地說,如果不編譯測試項目的話)實際上可以解決您的問題。 這是因為二進制運算符的標准答案是使用在類上帶有兩個參數的靜態方法。 C ++ STL廣泛使用此技術,我不知道嘗試將二進制運算符實現為實例方法(無論是否為實例方法)的原因。 太混亂了,沒有真正的好處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM