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

Chinaunix

標(biāo)題: 【結(jié)貼】C++虛表指針的一個(gè)問(wèn)題,和我預(yù)期的結(jié)果有點(diǎn)差距. [打印本頁(yè)]

作者: sampher    時(shí)間: 2013-09-27 14:49
標(biāo)題: 【結(jié)貼】C++虛表指針的一個(gè)問(wèn)題,和我預(yù)期的結(jié)果有點(diǎn)差距.
本帖最后由 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í)例頭部來(lái)操作。

  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ù)制代碼
到目前為止看起來(lái)一切正常。但是我如果把程序稍微改一下,就不能運(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è)成員變量,那么打印出來(lái)的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è)無(wú)效值。
  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ì)么?
那么上面改過(guò)以后的程序?yàn)槭裁磘his指針不對(duì)? 錯(cuò)在哪里?
作者: linux_c_py_php    時(shí)間: 2013-09-27 15:30
有意思?

..
作者: myworkstation    時(shí)間: 2013-09-27 16:00
回復(fù) 1# sampher


    你用的什么編譯器?通常應(yīng)該沒(méi)什么問(wèn)題的。
作者: cokeboL    時(shí)間: 2013-09-27 16:19
呵呵            
作者: sampher    時(shí)間: 2013-09-27 16:41
myworkstation 發(fā)表于 2013-09-27 16:00
回復(fù) 1# sampher

我在1L寫了,VC
作者: sampher    時(shí)間: 2013-09-29 09:27
我知道了,這個(gè)代碼GCC沒(méi)有問(wèn)題,因?yàn)镚CC是通過(guò)堆棧傳遞參數(shù)的方式,第一個(gè)參數(shù)保存的this指針。而VC編譯器在x86平臺(tái)的優(yōu)化結(jié)果是通過(guò)ecx/rcx寄存器保存,所以pVTable指針函數(shù)聲明的時(shí)候要寫void (__thiscall *pVTable)(Father*)才行。
這樣就可以很好的運(yùn)行了!




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2