Re: [問題] 關於Class指標的觀念

看板C_and_CPP (C/C++)作者 (「雄辯是銀,沉默是金」)時間11年前 (2013/08/28 00:18), 編輯推噓2(2029)
留言31則, 7人參與, 最新討論串7/19 (看更多)
: → Feis:哇. A 去哪了? 好酷喔 08/27 22:48 : → Feis:可以幫我 "轉回來" 嗎? 08/27 22:51 : → descent:你的意思是要轉回 member function pointer 嗎? 08/27 22:51 : → Feis:當然阿. 不是很合理嗎 Q_Q 08/27 22:52 : → descent:我以為只要能執行就好, member function pointer 08/27 22:53 : → descent:的版本我不確定可以成功 08/27 22:54 : → Feis:那如果 64-bit 整數塞到 32-bit 整數就印不出來嗎? 08/27 22:54 : → Feis:其實我也不是很懂. 討論一下 08/27 22:55 http://www.parashift.com/c++-faq-lite/cant-cvt-memfnptr-to-voidptr.html 看來無法將 void* 轉 member function pointer。 我用得方法其實是把 member function 當成 non member function, 再把 this 傳進去。 大概像是這樣。 A aa; (*(void(*)(A*))(addr) )(&aa); 難怪不能轉: void (A::*p)() = &A::func; 這個指標 assign 的動作原來有兩個部份, non-virtual function "剛好"可以這樣作。 non-virtual member function: 80486d1: c7 44 24 14 b4 86 04 movl $0x80486b4,0x14(%esp) 80486d8: 08 80486d9: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp) 80486e0: 00 virtual member function: void (A::*p)() = &A::func; 804873f: c7 44 24 14 01 00 00 movl $0x1,0x14(%esp) 8048746: 00 8048747: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp) 804874e: 0 難怪 printf 會得到 1。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.184.185.55

08/28 00:24, , 1F
不錯不錯~ 這些主題有互相輝映 (?)~
08/28 00:24, 1F

08/28 08:36, , 2F
這個 orz C++ ABI 各家都不同, 有些 compiler this 用
08/28 08:36, 2F

08/28 08:37, , 3F
register 傳啊... 推到 stack 上還是不行啊, 不要亂搞啊orz
08/28 08:37, 3F

08/28 08:42, , 4F
那一種compiler的第一個參數永遠是用A或AX/EAX傳啊
08/28 08:42, 4F

08/28 08:45, , 5F
用C call DirectX function官方說明文件就教你先取得 func
08/28 08:45, 5F

08/28 08:45, , 6F
pointer,然後第一個參數給this,我不確定這樣算不算正規作法
08/28 08:45, 6F
※ 編輯: descent 來自: 59.125.239.51 (08/28 09:18)

08/28 10:01, , 7F
elenya: 這作法應該是在高階語言層次.
08/28 10:01, 7F

08/28 10:02, , 8F
DirectX 應該是用 COM 來做的
08/28 10:02, 8F

08/28 10:04, , 9F
也就是為了實現多語言有相同介面. 在底層用 COM 統一
08/28 10:04, 9F

08/28 10:05, , 10F
不然 VB 也可以呼叫是怎麼辦到的 @_@ (神祕)
08/28 10:05, 10F

08/28 10:07, , 11F
就我個人觀點. C/C++ 設計是為了在多樣性硬體上運作.
08/28 10:07, 11F

08/28 10:08, , 12F
為了相容性. 語言本身才會變得這麼複雜.
08/28 10:08, 12F

08/28 10:09, , 13F
相對於現代許多語言的作法是把硬體抽象化有哲學上的不同
08/28 10:09, 13F

08/28 10:10, , 14F
C/C++ 沒有把硬體抽象化帶來的成本跟失去彈性
08/28 10:10, 14F

08/28 10:10, , 15F
但是為了相容性跟效率必須提供許多編譯器彈性空間
08/28 10:10, 15F

08/28 10:12, , 16F
還有. 不能把話說死. 我們應該用正面表列的方式看待 C/C++
08/28 10:12, 16F

08/28 10:12, , 17F
沒說一定能做的事情就是要當做不知道 (逃)
08/28 10:12, 17F

08/28 12:49, , 18F
對我來說除非預期這份程式碼僅限於在已知的環境下使用,否
08/28 12:49, 18F

08/28 12:50, , 19F
則能避免這類的問題就盡量避免.. 看到所有 undefined 當作
08/28 12:50, 19F

08/28 12:50, , 20F
會引起核彈爆炸,快逃XD
08/28 12:50, 20F

08/28 16:42, , 21F
所以可以希望有個大大幫這整串做個總結嗎OAO
08/28 16:42, 21F

08/28 16:42, , 22F
不過為甚麼debugger可以看到成員函數的位址0.0
08/28 16:42, 22F

08/28 18:37, , 23F
樓上,就 VC,單指多重繼承狀況下的成員函式指標,他需要
08/28 18:37, 23F

08/28 18:38, , 24F
該成員函數的開頭位址,這個會剛好存在該指標內。接著還需
08/28 18:38, 24F

08/28 18:38, , 25F
要一個 this 指標的修正值,假設叫 offset,會另外存在
08/28 18:38, 25F

08/28 18:39, , 26F
區域變數內,編譯器在傳遞成員函式指標做參數,會分別從
08/28 18:39, 26F

08/28 18:40, , 27F
這兩個位置去讀出內容,再 push 堆疊,讓 callee 能收到。
08/28 18:40, 27F

08/28 19:28, , 28F
所以就沒辦法單從成員函數指標拿到位址,只會出現bool?
08/28 19:28, 28F

08/28 19:35, , 29F
你來改用 VC 就可以,GCC 我不清楚
08/28 19:35, 29F

08/28 19:40, , 30F
可以說關於成員指標的實做被隱藏了
08/28 19:40, 30F

08/28 19:43, , 31F
對語言而言這使用者不需要知道,也不能讓他亂搞
08/28 19:43, 31F
文章代碼(AID): #1I7D4_rz (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1I7D4_rz (C_and_CPP)