看板 C_and_CPP 關於我們 聯絡資訊
之前有問過這問題 // 任意的非0值,因為0乘任何數都得0 #define SOME_VALUE 1 cout << (DWORD)static_cast<Base1*>((Drive*)SOME_VALUE)-SOME_VALUE << endl; cout << (DWORD)static_cast<Base2*>((Drive*)SOME_VALUE)-SOME_VALUE << endl; cout << (DWORD)static_cast<Base3*>((Drive*)SOME_VALUE)-SOME_VALUE << endl; 這會印 0 4 8 這之前文章我已知道為什麼了 不過我揣摩一下他註解 // 任意的非0值,因為0乘任何數都得0 這不知道再解釋什麼 如果把SOME_VALUE define 0 印出來全部都是0 發現 cout << (DWORD)static_cast<Base2*>((Drive*)SOME_VALUE); 就已經是0了 我粗淺的以為他轉型只會管要 "加" 多少offset 不過為啥他沒有+4.... 這跟他註解提到 "乘" 有關係嗎!? 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.207.215
holyspectral:為何不去問作者? 03/11 18:52
layan:keyword: offsetofclass 用來計算base類別在child類別的 03/11 19:36
layan:class layout 中的 offset value. 03/11 19:36
layan:這個 Macro 在 ATL 中找的到. 而該 value 通常被定義成 8 03/11 19:38
layan:它的值決不能為0,要是0的話怎麼乘都是0那就算不出 offset 了 03/11 19:39
layan:也因為它只是用來算offset, 所以SOME_VALUE值只要非 0 即可 03/11 19:40
layan:不一定要真的給一個真正在memory裡合法的 address. 03/11 19:41
layan:這個技巧應該是用在 COM Programming 裡比較常見. 03/11 19:42
layan:You can check CodeProject: ATL Under the Hood - Part 1 03/11 19:42
layan:我想原本寫這code的人應該在練習virtual table的概念. 03/11 19:44
layan:建議你直接去看CodeProject那篇文章code和你貼的一模一樣 03/11 19:45
QQ29:我問題就是@@為什麼會提到 乘...哪個地方會做乘法呢?? 03/11 22:35
layan:哦, SOME_VALUE 會被拿來乘以指標 (4 bytes) 03/11 22:48
layan:因為virtual table每個 entry 都是各個 base 的指標 03/11 22:49
layan:這也是為啥你印出來都是 4 的倍數 XDXD 03/11 22:49
QQ29:不太懂~ 為什麼會拿來*4 如果有*4那不是應該帶SOME_VALUE=2 03/12 00:31
QQ29:就得不一樣的結果嗎@@ 不太懂乘 是只哪邊~ 03/12 00:32
layan:SOME_VALUE的值不是拿來乘的 只是被拿來代表一個偽有效位址 03/12 00:43
layan:透過運算後可知BaseX*是在Derive class的 virtual table 的 03/12 00:44
layan:第 K 個 entry, 這個第K個entry再乘上 4, 就是印出來的結果 03/12 00:45
layan:再不懂的話 建議你去看一些 C++ virtual table 的部份 03/12 00:46
layan:或是那篇文章畫的一些 virtual table layout 圖. 03/12 00:46
QQ29:嗯我有看那個圖 但是我不懂 第K個entry 跟 SOME_VALUE 的關係 03/12 01:04
QQ29:跟您說 透過運算 得到entry 這之間 0跟非0 他運算到底是如何 03/12 01:05
QQ29:得知的呢? 03/12 01:06
layan:要是 SOME_VALUE 是0 , offset 永遠是 0, 代表 K 永遠是 0 03/12 10:27
LPH66:我有個不同看法...值為 0 的指標根據定義叫做 NULL pointer 03/12 11:00
LPH66:(標準是說整數 0 轉成指標時就是 NULL pointer) 03/12 11:00
LPH66:那麼即使它是這樣的繼承結構 但一個 NULL pointer 轉過去時 03/12 11:01
LPH66:還是得要是個 NULL pointer 才是... 03/12 11:01
LPH66:所以和 offset 什麼的比較沒什麼關係 03/12 11:02
LPH66:比較像是 layan 版友講的「只是被拿來代表一個偽有效位址」 03/12 11:02