[問題] 多重繼承與多型
開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
Windows Visual C++
問題(Question):
如同程式碼A,我的Class C同時繼承了Class A與Class B
大部份時候我希望用Class A的介面去存取(例中的add)
但在部份的情況下,我還是有必要用Class B的介面(例中的sub)
sub函式的預期結果是5,但程式碼A的寫法,卻會跑出7這個怪值
我想是因為虛擬函式的偏移位置不對,因為加上一些訊息輸出後
可以發現第二次呼叫的仍然是add() (如程式碼 A+msg)
我試著修改成程式碼B,雖然可以正確的跑出5,但我不知道這種寫法是不是安全的
(呃,看起來顯然不是)
因此我想問的是,像這種情況:
我有個Class A的指標,指向Class C的Object
而且我確定Class C有繼承Class B,並且實作了虛擬函式
那我要怎麼利用這個Class A指標,去呼叫Class B提供的虛擬函式?
預期的正確結果(Expected Output):
7 5 10
錯誤結果(Wrong Output):
7 7 10
程式碼(Code):(請善用置底文網頁, 記得排版)
A : http://ideone.com/cGHsx
A+msg : http://ideone.com/XGWnb
B : http://ideone.com/GVNbf (與A的差別在第30與第37行)
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 101.13.63.240
※ 編輯: james732 來自: 101.13.63.240 (02/14 08:34)
→
02/14 09:48, , 1F
02/14 09:48, 1F
→
02/14 09:54, , 2F
02/14 09:54, 2F
→
02/14 10:06, , 3F
02/14 10:06, 3F
→
02/14 10:13, , 4F
02/14 10:13, 4F
推
02/14 10:30, , 5F
02/14 10:30, 5F
→
02/14 10:31, , 6F
02/14 10:31, 6F
推
02/14 10:36, , 7F
02/14 10:36, 7F
→
02/14 10:38, , 8F
02/14 10:38, 8F
→
02/14 10:41, , 9F
02/14 10:41, 9F
→
02/14 10:42, , 10F
02/14 10:42, 10F
→
02/14 10:44, , 11F
02/14 10:44, 11F
→
02/14 10:44, , 12F
02/14 10:44, 12F
→
02/14 10:45, , 13F
02/14 10:45, 13F
→
02/14 10:49, , 14F
02/14 10:49, 14F
→
02/14 10:50, , 15F
02/14 10:50, 15F
→
02/14 10:52, , 16F
02/14 10:52, 16F
→
02/14 10:53, , 17F
02/14 10:53, 17F
→
02/14 10:57, , 18F
02/14 10:57, 18F
→
02/14 10:58, , 19F
02/14 10:58, 19F
我沒有強調一個重點,這兩個 parent class 裡,有一個不是我寫的
它其實是 MFC 的 CDialog class
所以沒辦法在 class A, class B 上面再加一層 Abstract
另外,我一直不知道 dynamic_cast 什麼時候會用到,這篇總算讓我懂了 XD
推
02/14 11:00, , 20F
02/14 11:00, 20F
→
02/14 11:01, , 21F
02/14 11:01, 21F
哎呀,是我沒有說清楚
其實我的情況還會有一個 D, 同樣繼承 A 與 B
在程式執行的時候會藉由建立 C 或 D 的實體,來做不同的事情
而且工作會改變的是 B 介面的部份
用原本的例子改起來就像這樣 http://ideone.com/RUFzz
我有點驚訝這兩行程式碼竟然可以正確執行,得到我要的答案
A *p = new D;
cout << ((C *)p)->sub() << endl;
不過總覺得看起來好怪異...
→
02/14 11:12, , 22F
02/14 11:12, 22F
推
02/14 11:18, , 23F
02/14 11:18, 23F
→
02/14 11:18, , 24F
02/14 11:18, 24F
→
02/14 11:18, , 25F
02/14 11:18, 25F
我也覺得很恐怖,所以才會想要轉成B
大概是類似這樣的感覺,會比轉成C還要合理
A *p = new C;
((B *)p)->sub();
delete p;
p = new D;
((B *)p)->sub();
→
02/14 11:50, , 26F
02/14 11:50, 26F
→
02/14 11:54, , 27F
02/14 11:54, 27F
→
02/14 11:56, , 28F
02/14 11:56, 28F
→
02/14 12:31, , 29F
02/14 12:31, 29F
→
02/14 12:33, , 30F
02/14 12:33, 30F
→
02/14 12:35, , 31F
02/14 12:35, 31F
→
02/14 12:37, , 32F
02/14 12:37, 32F
推
02/14 15:51, , 33F
02/14 15:51, 33F
→
02/14 15:52, , 34F
02/14 15:52, 34F
→
02/14 15:53, , 35F
02/14 15:53, 35F
唔,其實 CDialog 並沒有 pure virtual function (應該吧?)
我承認這裡是我的例子舉得不好XD
→
02/15 09:30, , 36F
02/15 09:30, 36F
→
02/15 09:32, , 37F
02/15 09:32, 37F
→
02/15 09:33, , 38F
02/15 09:33, 38F
可是我需要B的介面...XD
※ 編輯: james732 來自: 101.13.7.106 (02/15 09:46)
推
02/15 17:33, , 39F
02/15 17:33, 39F
→
02/15 21:16, , 40F
02/15 21:16, 40F
→
02/16 08:53, , 41F
02/16 08:53, 41F
→
02/16 08:54, , 42F
02/16 08:54, 42F
推
02/17 22:41, , 43F
02/17 22:41, 43F
→
02/22 09:59, , 44F
02/22 09:59, 44F
討論串 (同標題文章)