- 論壇徽章:
- 0
|
本帖最后由 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í)例頭部來操作。
- 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ù)制代碼 程序的輸出是:到目前為止看起來一切正常。但是我如果把程序稍微改一下,就不能運(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,那么程序直接崩潰,像下面這樣:
- class Father
- {
- public:
- int i;
- Father(){i=22;}
- virtual void f(){printf("f:%d\n",i);}//這一行打印的i是個(gè)無效值。
- 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ì)么?
那么上面改過以后的程序?yàn)槭裁磘his指針不對(duì)? 錯(cuò)在哪里? |
|