導航:首頁 > 源碼編譯 > 虛函數表編譯器如何實現

虛函數表編譯器如何實現

發布時間:2023-03-27 16:01:02

Ⅰ C++虛表問題

虛函數表是編譯器用來實現多態的方法。一般來說,虛函數表是一個數組,數組的元素是虛函數的指針。每個對象都會有一個虛函數表,當在某個對象上調用虛函數時,通過查詢這個表來獲得繼承層次中到底哪個函數被實際調用。
對於一個類如果有虛函數,就會在這個類中創建一個虛表,也就會產生一個虛指針指向這個虛表。
既然有一個指針指向了虛表,這個類派生後,在派生類中就不必再創建虛表,如果派生類還有自己的虛函數,那麼只在派生類中創建該虛函數的一個虛表,產生一個指向該虛表的指針。
為每個類設置虛表,初始化虛指針,為虛函數調用插入代碼都是自動發生的,不必擔心這些。

(我看到過虛繼承下虛表問題的分析,直接繼承下沒看過,特此又分析了一下,修改)
#include<iostream>
using namespace std;
class A
{

public:
virtual void a(){};
};
class B:public virtual A
{

public:
virtual void b(){};

};

int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
}

對於這個程序,你大概是在vc6.0下運行的吧,在vc下結果是4和12。我用的編譯器是g++,對於這段程序的結果確實都為4.

因編譯器不同導致結果不同這個我倒是沒注意,這樣可以得出,對虛函數這里的處理機制和編譯器也是有關的,g++編譯器還是更符合新的標准。

把虛繼承virtual去掉再運行,在codeblocks下,g++編譯運行結果都為4. vc下編譯運行結果也都為4.

在分析一個例子:
#include<iostream>
using namespace std;
class A
{
char j[3];
public:
virtual void a(){};
};
class B:public A
{
char k[3];
public:
virtual void b(){};

};
class C:public B
{
char m[3];
public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
這個直接繼承的例子,在vc下,codeblocks下結果都為 8 12 16.

再看這個直接繼承的例子:
#include<iostream>
using namespace std;
class A
{

public:
virtual void a(){};
};
class B:public A
{

public:
virtual void b(){};

};
class C:public B
{

public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
vc下河codeblocks下結果都為 4. 這兩個程序說明,直接繼承下,輸出結果應當是本類所佔的位元組加父類數據成員所佔位元組,父類的虛指針所佔位元組沒有加上。

加入虛繼承後:
#include<iostream>
using namespace std;
class A
{
char j[3];
public:
virtual void a(){};
};
class B:public virtual A
{
char k[3];
public:
virtual void b(){};

};
class C:public virtual B
{
char m[3];
public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
這段代碼,在codeblocks下g++編譯運行結果為:8 16 24.
在vc6.0下編譯運行結果為:8 20 32.
能夠分析出codeblocks下的結果是本類加上父類的結果。vc下是 本類加父類後又加了4個位元組。

但是這段代碼:
#include<iostream>
using namespace std;
class A
{

public:
virtual void a(){};
};
class B:public virtual A
{

public:
virtual void b(){};

};
class C:public virtual B
{

public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
codeblocks下編譯運行結果為 4 4 4.
vc下編譯運行結果為:4 12 20.
從結果來看,vc下是 本類加父類後又加了4個位元組。而codeblocks結果就不再是本類加父類的結果(這個有點迷茫)。

閱讀全文

與虛函數表編譯器如何實現相關的資料

熱點內容
車銑復合雕花編程教學 瀏覽:904
android圖片等比例縮放 瀏覽:355
javaset使用方法 瀏覽:339
modbus轉opc源碼 瀏覽:321
csharp串口編程 瀏覽:544
山東雙線伺服器雲伺服器 瀏覽:865
帶動程序員技術氛圍的活動有哪些 瀏覽:551
華為捐贈源碼 瀏覽:591
ccs編譯程序一直彈debug 瀏覽:47
安卓手機如何調白圖片 瀏覽:355
什麼牌子的安卓平板最好用 瀏覽:172
keil編譯顯示目標沒有建立 瀏覽:793
安卓收銀機如何安裝列印機驅動 瀏覽:820
電動車什麼app上買 瀏覽:531
墨西哥pdf 瀏覽:712
python圖形界面編程 瀏覽:958
暫停加密服務 瀏覽:278
易語言編程系統下載 瀏覽:55
linux創建資料庫命令 瀏覽:927
佛系程序員的道路 瀏覽:409