看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) NO 問題(Question): 最近剛初學 Template 在寫繼承的時候遇到一個問題 假設 Base class A_base 有如下的運算子重載 friend A_base operator+(const A_base &lhs,const A_base &rhs) { ... return Temp_A_base; } 另有 Derived class A_derived:public A_base{...} 我希望可以不用重寫一個重載函式(因為實際上內容完全相同)如下 friend A_derived operator+(const A_derived &lhs,const A_derived &rhs) { ... return Temp_A_derived; } 所以我嘗試用 Template 來簡化 程式碼如下 template<typename T> inline T operator+( const T &lhsob, const T &rhsob ) { ... return static_cast<T>( Temp_result ); } 然後在 class 內放 friend A_derived operator+ <A_derived> ( const A_derived& , const A_derived& ); 經測試可以運作無誤 但問題來了 我在想,這樣的寫法會不會讓引用我頭檔的使用者 寫下不是我所寫的型別的加法時不小心被我這個 Template 具現化,以致結果出錯呢? 例如他寫下 B_type a,b; a + b; A_derived c,d; c + d; 然後就出錯這樣 為了解決這個問題 想請問一下 有沒有辦法指定他只能具現化特定型別的函數呢? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.47.222.76 ※ 編輯: birdhackor 來自: 114.47.222.76 (04/29 00:06)
loveme00835:內容為什麼會一樣呢? 04/29 01:41
bleed1979:virtual friend function可解?? 04/29 08:02
birdhackor:因為它只是把一個成員變數相加而已 04/29 08:04
birdhackor:virtual friend function 可以達成回傳derived class 04/29 08:25
birdhackor:的效果嗎? 04/29 08:26
bleed1979:不行,可是回傳值很不一般。 04/29 08:32
birdhackor:那還是沒辦法解決說...因為我的目的是讓他傳回 04/29 09:24
birdhackor:derived class object 04/29 09:24
順便問個問題,照理來說應該有很多函示庫有定義到 像是 template<typename T> inline T operator+( const T &lhsob, const T &rhsob ) 這樣的template 為甚麼具現化的時候不會出錯呢? ※ 編輯: birdhackor 來自: 114.47.222.76 (04/29 09:26)
loveme00835:該成員變數是從basse class繼承來的, 所以一樣? 04/29 15:02
birdhackor:對 04/29 15:45
loveme00835:你case的是duplicate codes, 這改一下設計就好了, 利 04/29 17:30
loveme00835:用is a關係復用程式碼, 再透過轉呼叫運算子去掉friend 04/29 17:31
loveme00835:這種雙向相依的程式碼 http://codepad.org/q2K2f6zk 04/29 17:32
loveme00835:如果本來的 code 可以 work, 你應該重複思考一下為什 04/29 17:41
loveme00835:麼子類別可以存取父類別的資料成員? 有這個必要嗎? 04/29 17:42
loveme00835:如果有, 那有必要寫成兩個類別嗎? 04/29 17:42
birdhackor:我寫的是矩陣運算 Base class 是廣義矩陣 04/29 17:49
birdhackor:在廣義矩陣上,定義方陣與行列向量這三個Derived class 04/29 17:50
birdhackor:矩陣加減乘法是完全相同的 但方陣額外有 trace det 04/29 17:51
birdhackor:diagonal 等方法是廣義矩陣沒有的 04/29 17:52
birdhackor:行列向量則是有長度運算是其他沒有的 04/29 17:52
loveme00835:ok 04/29 18:04
birdhackor:繼承的技術我沒啥問題...寫法很多...我只是想知道能不 04/29 18:06
birdhackor:不能用 template 來偷懶... 04/29 18:06
loveme00835:問題是根本沒有東西可以給你偷懶阿... 硬是要開大門 04/29 18:08
loveme00835:就只能用 yoco 大的方式再把不想走的關起來 04/29 18:09
loveme00835:一開始 "內容完全相同" 這點你就該注意到寫法是有問題 04/29 18:11
loveme00835:的, 然後又要用 template 來影響其他沒關係的類別, 04/29 18:12
loveme00835:現在 work 了, 之後也會有問題的 04/29 18:13
birdhackor:請問內容完全相同這點哪裡有問題? 他們的操作一樣所以 04/29 18:16
birdhackor:寫出來就一樣阿... 04/29 18:17
loveme00835:內容相同表示他們在做同樣的事情, 操作一樣, 存取的成 04/29 18:28
loveme00835:員都是從父類別繼承來的, 表示這個 method 應該只存在 04/29 18:28
loveme00835:於父類別, 你這是為了讓子類別也能擁有一樣的 + 操作 04/29 18:29
loveme00835:但是忽略了參數用 & 傳遞的涵義: 可以透過 is a 關係 04/29 18:30
loveme00835:叫用父類別的版本, 所以不需要為了best match來多複製 04/29 18:31
loveme00835:相同程式碼, 你只需要考慮回傳時會不會被 slice 掉 04/29 18:31
loveme00835:你應該要仔細思考operator+ 的signature究竟差別在哪 04/29 18:38
birdhackor:我不是為了best match才去複製... 04/29 18:38
birdhackor:我的想法是,既然是用&傳遞,就可以直接用動態定型 04/29 18:40
birdhackor:使用父類別已經宣告好的operator+ 04/29 18:40
loveme00835:存取父類別的成員, 不需要透過子類別 reference 04/29 18:40
birdhackor:A_base operator+(const A_base &lhs,const A_base &rh 04/29 18:42
birdhackor:的寫法後面雖然動態型別仍為子類別,回傳卻會被傳成 04/29 18:43
birdhackor:父類別,但我希望他回傳的是子類別 04/29 18:43
birdhackor:但我又不想宣告兩個像是 Base operator+( Base const & 04/29 18:44
birdhackor:Derived operator+( Derived const &lhs.... 04/29 18:45
birdhackor:這樣子,實際上只有型別上有差的overload 04/29 18:45
birdhackor:所以才把腦筋動到template上 04/29 18:46
loveme00835:所以重點其實是在 signature 的 adapt 而不是用模板來 04/29 20:54
loveme00835:作 codegen 04/29 20:55
loveme00835:用了模板你把它合成一份程式碼, 但是卻產生了更多不必 04/29 21:02
loveme00835:要的程式碼 04/29 21:03