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

虛函數表編譯器如何實現

發布時間: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結果就不再是本類加父類的結果(這個有點迷茫)。

閱讀全文

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

熱點內容
新電腦管家下載好怎麼解壓 瀏覽:526
php獲取介面數據 瀏覽:763
最後的命令 瀏覽:921
如何添加手機app桌面快捷圖標 瀏覽:427
ui設計師與程序員 瀏覽:417
壽司pdf 瀏覽:828
pythonbg是什麼 瀏覽:248
c數值演算法程序大全 瀏覽:785
android整點報時 瀏覽:221
稀土pdf 瀏覽:536
單片機電子鎖 瀏覽:596
通達信機智資金流指標公式源碼 瀏覽:216
php安裝xsl擴展 瀏覽:842
python如何使用help 瀏覽:367
上汽榮威app在哪裡查詢 瀏覽:903
冰櫃壓縮機溫度108 瀏覽:720
阿里雲郵smtp伺服器地址 瀏覽:252
解壓館認知理解 瀏覽:239
為什麼使用非官方伺服器會封號 瀏覽:9
佛山加密文檔軟體 瀏覽:813