亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3144 | 回復(fù): 5
打印 上一主題 下一主題

[C++] 【結(jié)貼】C++虛表指針的一個(gè)問題,和我預(yù)期的結(jié)果有點(diǎn)差距. [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2013-09-27 14:49 |只看該作者 |倒序?yàn)g覽
本帖最后由 sampher 于 2013-09-29 09:28 編輯

我知道C++內(nèi)存對(duì)象模型的基本知識(shí),對(duì)于一個(gè)有virtual函數(shù)的類而言,實(shí)例的第一個(gè)size_t大小是指向虛表的指針。
因此我寫了下面一個(gè)在vc下編譯的小程序,是可以執(zhí)行的。
這個(gè)類有3個(gè)函數(shù),分別叫f/g/h,我不用類的方法調(diào)用,而是用指向虛表的實(shí)例頭部來操作。

  1. class Father
  2. {
  3. public:
  4.         int i;
  5.         Father(){i=22;}
  6.         virtual void f(){printf("f\n");}
  7.         virtual void g(){printf("g\n");}
  8.         virtual void h(){printf("h\n");}
  9. };
  10. typedef void (*pFather)(Father*);
  11. int main(int argc, char* argv[])
  12. {
  13.         Father* pf=new Father;
  14.         pFather *pVtable=*(pFather**)(pf);
  15.         pVtable[0](pf);
  16.         pVtable[1](pf);
  17.         pVtable[2](pf);
  18.         delete pf;
  19.         return 0;
  20. }
復(fù)制代碼
程序的輸出是:

  1. f
  2. g
  3. h
復(fù)制代碼
到目前為止看起來一切正常。但是我如果把程序稍微改一下,就不能運(yùn)行了。我發(fā)現(xiàn)pVtable[0](pf)在調(diào)用f函數(shù)的時(shí)候,在debug狀態(tài)下觀看f函數(shù)調(diào)用時(shí)的this指針,發(fā)現(xiàn)并不是pf。這個(gè)非常奇怪。如果我在函數(shù)f里面操作一個(gè)成員變量,那么打印出來的i的值是一個(gè)非常大的值例如17111262。如果我要操作i成員,例如++i,那么程序直接崩潰,像下面這樣:

  1. class Father
  2. {
  3. public:
  4.         int i;
  5.         Father(){i=22;}
  6.         virtual void f(){printf("f:%d\n",i);}//這一行打印的i是個(gè)無效值。
  7.         virtual void g(){printf("g:%d\n",++i);}//++i導(dǎo)致崩潰。
  8.         virtual void h(){printf("h\n");}
  9. };
  10. typedef void (*pFather)(Father*);
  11. int main(int argc, char* argv[])
  12. {
  13.         Father* pf=new Father;
  14.         pFather *pVtable=*(pFather**)(pf);
  15.         pVtable[0](pf);
  16.         pVtable[1](pf);
  17.         pVtable[2](pf);
  18.         delete pf;
  19.         return 0;
  20. }
復(fù)制代碼
這是為什么呢? pVtable在調(diào)用的時(shí)候,類的成員函數(shù)的第一個(gè)參數(shù)默認(rèn)就是實(shí)例的指針對(duì)么?
那么上面改過以后的程序?yàn)槭裁磘his指針不對(duì)? 錯(cuò)在哪里?

論壇徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46處女座
日期:2013-10-24 14:25:01酉雞
日期:2014-04-07 11:54:15
2 [報(bào)告]
發(fā)表于 2013-09-27 15:30 |只看該作者
有意思?

..

論壇徽章:
17
處女座
日期:2013-08-27 09:59:352015亞冠之柏太陽神
日期:2015-07-30 10:16:402015亞冠之薩濟(jì)拖拉機(jī)
日期:2015-07-29 18:58:182015年亞洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥豬
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56雙子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
3 [報(bào)告]
發(fā)表于 2013-09-27 16:00 |只看該作者
回復(fù) 1# sampher


    你用的什么編譯器?通常應(yīng)該沒什么問題的。

論壇徽章:
36
子鼠
日期:2013-08-28 22:23:29黃金圣斗士
日期:2015-12-01 11:37:51程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-12-14 06:20:00CU十四周年紀(jì)念徽章
日期:2015-12-22 16:50:40IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-01-25 06:20:0015-16賽季CBA聯(lián)賽之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16賽季CBA聯(lián)賽之福建
日期:2016-04-07 11:25:2215-16賽季CBA聯(lián)賽之青島
日期:2016-04-29 18:02:5915-16賽季CBA聯(lián)賽之北控
日期:2016-06-20 17:38:50技術(shù)圖書徽章
日期:2016-07-19 13:54:03程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-08-21 06:20:00
4 [報(bào)告]
發(fā)表于 2013-09-27 16:19 |只看該作者
呵呵            

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2013-09-27 16:41 |只看該作者
myworkstation 發(fā)表于 2013-09-27 16:00
回復(fù) 1# sampher

我在1L寫了,VC

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2013-09-29 09:27 |只看該作者
我知道了,這個(gè)代碼GCC沒有問題,因?yàn)镚CC是通過堆棧傳遞參數(shù)的方式,第一個(gè)參數(shù)保存的this指針。而VC編譯器在x86平臺(tái)的優(yōu)化結(jié)果是通過ecx/rcx寄存器保存,所以pVTable指針函數(shù)聲明的時(shí)候要寫void (__thiscall *pVTable)(Father*)才行。
這樣就可以很好的運(yùn)行了!
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP