亚洲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)操作。
class Father
{
public:
int i;
Father(){i=22;}
virtual void f(){printf("f\n");}
virtual void g(){printf("g\n");}
virtual void h(){printf("h\n");}
};
typedef void (*pFather)(Father*);
int main(int argc, char* argv[])
{
Father* pf=new Father;
pFather *pVtable=*(pFather**)(pf);
pVtable[0](pf);
pVtable[1](pf);
pVtable[2](pf);
delete pf;
return 0;
}
復(fù)制代碼
程序的輸出是:
f
g
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,那么程序直接崩潰,像下面這樣:
class Father
{
public:
int i;
Father(){i=22;}
virtual void f(){printf("f:%d\n",i);}//這一行打印的i是個(gè)無(wú)效值。
virtual void g(){printf("g:%d\n",++i);}//++i導(dǎo)致崩潰。
virtual void h(){printf("h\n");}
};
typedef void (*pFather)(Father*);
int main(int argc, char* argv[])
{
Father* pf=new Father;
pFather *pVtable=*(pFather**)(pf);
pVtable[0](pf);
pVtable[1](pf);
pVtable[2](pf);
delete pf;
return 0;
}
復(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