1樓:網友
基類a定義了乙個虛擬函式 virtual void fun(),那麼編譯器在編譯的時候,自動會為類a生成乙個名叫「__vfptr」的成員常量指標,是乙個函式指標,排在類成員的最前面。這個函式指標指向類a對應的虛擬函式表(vftable),該虛擬函式表儲存了a::fun()和類a的其他虛擬函式位址。
在例項化a的物件a時,編譯器自動在a物件的前面加上「__vfptr」成員指標(通過vc單步除錯可以看出來),它指向a的虛擬函式表(vftable)。派生類b繼承a之後,會將基類的虛擬函式表繼承過來,並將自己定義的虛擬函式新增到虛擬函式表中,這樣就形成了派生類b的虛擬函式表,在編譯的時候,編譯器也會自動會在派生b類的前面加上「__vfptr」的指標成員,指向b的虛擬函式表。
基類和派生類的指標之前型別轉換,會產生指標切割,通常基類指標指向的記憶體域會比派生類指向的記憶體域要小;這樣基類的指標指向派生類時,就縮小了記憶體域,這樣向上轉陸手換,直接賦值就行,不需要強制型別轉換;如果將派生類指標指向基類的物件,派生類的指標的指向的記憶體域會縮小,這樣就需要進行強制型別轉換。如問題的**所示 pb = static_cast(a);
以上提出的幾個問題:
pb->fun();呼叫的是a::fun(),理由是基類a例項化物件a時,生成乙個「__vfptr」成員指標,指向a的虛擬函式表,a的虛擬函式表中存在a::fun()函式。
此時將b的物件指標pb強制轉換型別指向a,產生了位址切割,對於m_b這個派生類定義的成員來說,它的值是不可預期的。此時pb->_vfptr也同時被賦予a->_vfptr,指向a的vftable,呼叫pb->fun()時,實際上呼叫了a虛擬函式表裡面的a::fun()瞎型。
對於a::fun()不為virtual時,也就不會存在虛擬函式表中,這樣b::fun();是將基類a::
fun()實磨悉猜現隱藏了,故a::fun()不為虛擬函式時,pb->fun()呼叫的是b::fun()。
c語言問題求助,C語言問題求助!!!!
include void sort int p1,int p2,int p3 else if p1 p3 else else if p2 p3 if p1 看下函式形參和實參的概念。include main void sort int p1,int p2,int p3 少括號 else 少括號 el...
求助C語言高手,求助C語言高手!
inlcude include int main file fopen a.dat rw 開啟a.bat檔案,存入file指標裡 for i 0 i 200 i return 0 返回 return 這就是現在的大學生 在學校混文憑!題目出的不錯,你們老師有點水平 一樓的做得不太完整,隨機數有問題,...
C 中,cout如何控制寬度,c 中用cout函式怎樣實現格式輸出
a 1 數字進位制 使用hex dec oct控制輸出數字的進位制 2 如何對齊 使用setw控制寬內度 3 設定精度 使用setprecision控制輸容出精度4 填充字元 使用setfill控制填充字元5 控制格式 使用setioflags ios base fmtflags mask 來控制 ...