[問題] 多重繼承下(不使用虛擬繼承)使用多型

看板C_and_CPP (C/C++)作者 (台灣自耕農代表)時間14年前 (2012/05/08 21:55), 編輯推噓7(7017)
留言24則, 9人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VC6.0 問題(Question): 希望建立同時具有多型及多重繼承優點的物件 錯誤結果(Wrong Output): compile出現ambiguous error 程式碼(Code):(請善用置底文網頁, 記得排版) 一般對於多型的用法是把指向衍生類別的指標指定給指向基礎類別的指標, 但以上用法在多重繼承的架構下出現問題。 程式碼如下: class Base { virtual Func_1(){}; virtual Func_2(){}; virtual Func_3(){}; } class Derived_1: public Base { virtual Func_1() { Do something... } } class Derived_2: public Base { virtual Func_2() { Do something... } } class Derived_3: public Base { virtual Func_3() { Do something... } } class Foo: public Derived_1, public Derived_2 { } class Qoo: public Derived_2, public Derived_3 { } Base* Object = new Foo; // ambiguous // 希望能使用下列功能 // Object->Func_1(); // Object->Func_2(); // Object->Func_3(); 補充說明(Supplement): 說明一下為什麼這樣寫。 首先Base為基底抽像類別這沒問題, Base的下一層負責"個別實做"一個功能, 接著最後的Object可以自行選擇想要具備哪些實做功能(透過多重繼承), 老練的看倌或許馬上就會說:這不就是組合嗎? 的確,組合的概念就是為了化簡多重繼承的複雜度而產生, 但反過來說,我也可以用多重繼承來達到組合的功能。 為什麼要這麼做? 因為我有使用多型的需求。 多型有個好處,當衍生類別沒有覆寫虛擬函式時compiler會使用基礎類別的方法, 也就是說在解決 ambiguous 的情形下, Object->Func_3 應該要能執行 Base 裡面的 Func_3, 也就是空函式,這是我想要的。 如果使用組合的話我只要在Foo裡面實做 Func_1~3 的物件(3是空的), 以這個例子來說沒什麼困難, 但實際情況是,Base 裡面的 virtual function 可能非常多, 然而Foo只需要其中兩、三個實做,也就是說我必須寫十幾個空物件, 另外除了Foo,我還有Qoo、Hoo... 而且每當我在 Base 裡增加一個虛擬函式, 用組合寫法就得在每個類別裡面多加一個物件, 這看起來不像是良好的設計模式。 然後我也沒辦法用虛擬繼承, 因為那會使 Derived 類別的覆寫無效化。 // 如果嫌以上說明過於冗長, 簡短的說就是: 我需要許多物件,這些物件必須有共同的基礎類別(為了使用多型)與介面, 譬如說 Func_1(); Func_2(); ... Func_20(); 我希望個別物件能夠只針對特定介面動作,其餘無反應。 謝謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 123.195.0.180

05/08 22:16, , 1F
.0.
05/08 22:16, 1F

05/08 22:44, , 2F
看起來應該可以用 function pointer
05/08 22:44, 2F

05/08 22:45, , 3F

05/08 22:46, , 4F
類似mixin的奇怪做法XD
05/08 22:46, 4F

05/08 23:06, , 5F

05/09 00:01, , 6F

05/09 00:15, , 7F
三樓的code改成不串起來 http://ideone.com/biPR0
05/09 00:15, 7F

05/09 00:15, , 8F
等於永遠單線繼承
05/09 00:15, 8F

05/09 00:36, , 9F
話說回來原來的 ambiguous 其實就是死亡鑽石....
05/09 00:36, 9F

05/09 00:39, , 10F
BTW, 你真的需要繼承來透過父類別介面來對子類別物件
05/09 00:39, 10F

05/09 00:39, , 11F
樓上的看起來有點像 decorator pattern @@
05/09 00:39, 11F

05/09 00:40, , 12F
操作嗎? 或者只是想得到某些功能而已?
05/09 00:40, 12F

05/09 00:45, , 13F
05/09 00:45, 13F

05/09 00:50, , 14F
http://codepad.org/5wcNQmvQ 加一個 callal 介面
05/09 00:50, 14F

05/09 01:06, , 15F
回love大, 是的. 這個東西其實是我在做FSM的一部分, 那些
05/09 01:06, 15F

05/09 01:07, , 16F
Foo都是一個狀態.
05/09 01:07, 16F

05/09 02:13, , 17F
05/09 02:13, 17F

05/09 03:15, , 18F
http://codepad.org/HUMVZg75 策略模式, 虛擬繼承
05/09 03:15, 18F

05/09 03:38, , 19F
產生 ambiguous 是因為你不用虛擬繼承, 而用了虛擬繼
05/09 03:38, 19F

05/09 03:39, , 20F
承還會 ambiguous 表示有兩個以上的父類別都為你覆寫
05/09 03:39, 20F

05/09 03:40, , 21F
了同一個函式
05/09 03:40, 21F

05/09 13:39, , 22F
大家都不喜歡gist??總覺得codepag開好慢
05/09 13:39, 22F

05/09 18:23, , 23F
gist 不能跑結果啊...codepad 時快時慢,有時候還真的等到
05/09 18:23, 23F

05/09 18:23, , 24F
想翻臉,不過現在有 ideone 當替代囉
05/09 18:23, 24F
文章代碼(AID): #1FgIMtc3 (C_and_CPP)
文章代碼(AID): #1FgIMtc3 (C_and_CPP)