[問題] C++運算子重載和繼承合用,會導致混亂

看板C_and_CPP作者 (問號)時間10年前 (2014/06/08 14:25), 10年前編輯推噓6(6025)
留言31則, 8人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) cygwin64 問題(Question): 最近正在省思我要把C++定位成怎樣的工具 C++的多功能的確很容易導致誤用 現在寫C++時我都會把"避免過度設計"這句話放在心中 以上都是題外話,我要向各位請教的是C++技術上的問題 之所以說上面這些屁話,是因為這個問題是在思索上面的哲學問題而發現的 下方的程式碼,類A定義了operator*和operator+ 類B繼承自類A,因為方便直接沿用類A的operator+,但定義了自己的operator* 最後在main函數中宣告兩個B實例b1和b2,並執行(b2+b1)*3.0 直觀上會以為operator*是調用類B的 但事實上是調用類A的,因為在執行operator+時回傳的是A reference 想請問C++老手,這樣的問題是用什麼方法解決? 做type conversion,多型,還是單純不要亂用operator overload? 程式碼(Code):(請善用置底文網頁, 記得排版) #include <iostream> using namespace std; class A { public: A& operator+(const A& rhs){cout<<"A& A::operator+(const A&)\n";} A& operator*(const double& rhs){cout<<"A& A::operator*(const double&)\n";} }; class B: public A { public: B& operator*(const double& rhs){cout<<"B& B::operator*(const double&)\n";} B& operator=(const A& rhs){cout<<"B& B::operator=(const A&)\n";} B& operator=(const B& rhs){cout<<"B& B::operator=(const B&)\n";} }; int main() { B b1, b2; b1=(b2+b1)*3.0; /* output: A& A::operator+(const A&) A& A::operator*(const double&) B& B::operator=(const A&) */ } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.120.19.5 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1402208713.A.FD2.html ※ 編輯: frankhsu421 (140.120.19.5), 06/08/2014 14:28:38

06/08 15:24, , 1F
virtual? not sure
06/08 15:24, 1F

06/08 15:31, , 2F
06/08 15:31, 2F

06/08 15:43, , 3F
virtual
06/08 15:43, 3F

06/08 15:48, , 4F
要先想清楚你這麼做的實際情境是甚麼? 為什麼你可以偷懶.
06/08 15:48, 4F

06/08 15:49, , 5F
嗯... 樓上的說法才正確 xDD
06/08 15:49, 5F

06/08 15:59, , 6F
四樓的意思是?!
06/08 15:59, 6F

06/08 16:25, , 7F
當你覆載加減乘除,表示這個type能像數字那樣運算
06/08 16:25, 7F

06/08 16:26, , 8F
但數學運算子只能接受相同的type運算
06/08 16:26, 8F

06/08 16:27, , 9F
一旦你混用繼承表示不同type也能相加,就背離常識了
06/08 16:27, 9F

06/08 16:28, , 10F
因此這時候就不該用operator+而是另一個function
06/08 16:28, 10F

06/08 16:29, , 11F
因為這個加法與數學上的加法在基本概念上就不一樣了
06/08 16:29, 11F

06/08 16:30, , 12F
(當然operator+的確可以是virtual,但通常不會這樣搞)
06/08 16:30, 12F

06/08 16:30, , 13F
恩感謝michael0728n的回答
06/08 16:30, 13F

06/08 16:33, , 14F
會想這樣做,是因為認為物件導向就是可以沿用code
06/08 16:33, 14F

06/08 16:36, , 15F
每次繼承了一個類,想再沿用該類的operator都會出現
06/08 16:36, 15F

06/08 16:37, , 16F
問題,想說我該不會每繼承一次,operator都要重寫吧
06/08 16:37, 16F

06/08 16:39, , 17F
看來是誤會operator overload的設計目的
06/08 16:39, 17F

06/08 16:41, , 18F
感謝littleshan導正觀念
06/08 16:41, 18F

06/08 16:48, , 19F
它是繼承一個 object * double 所以我是覺得還好啦
06/08 16:48, 19F

06/08 16:48, , 20F
不過還是看使用情境就是XD
06/08 16:48, 20F

06/08 19:57, , 21F
每次我看到operator+-*/我都會想 真的有必要嗎 XD
06/08 19:57, 21F

06/08 19:58, , 22F
有些是受c#的影響 把register event寫成operator+=
06/08 19:58, 22F

06/08 19:58, , 23F
這種code老實講看幾次都覺得怎麼看怎麼怪....
06/08 19:58, 23F

06/08 20:22, , 24F
這樣寫滿方便的啊xdd
06/08 20:22, 24F

06/09 01:54, , 25F
[題外話] C# 的 event 設計根本莫名奇妙...
06/09 01:54, 25F

06/09 12:45, , 26F
他的event其實基本上跟boost::signal2完全同出一輒
06/09 12:45, 26F

06/09 12:46, , 27F
只是寫法變得很奇怪而已 我第一次看到有人在C++用+=
06/09 12:46, 27F

06/09 12:46, , 28F
來註冊的時候就把他叫過來問 果然是學C#的 OTZ
06/09 12:46, 28F

06/09 12:47, , 29F
不過後來看到這樣寫的人越來越多 好吧 當作業界慣例好了
06/09 12:47, 29F

06/09 13:23, , 30F
集合用+-描述還算正常吧
06/09 13:23, 30F

06/09 13:24, , 31F
沒有operator+-*/ 讀寫向量運算會想殺人XD
06/09 13:24, 31F
文章代碼(AID): #1Jb079_I (C_and_CPP)