如何選擇網(wǎng)站公司網(wǎng)絡(luò)銷售平臺(tái)有哪些
類的虛表
每個(gè)包含了虛函數(shù)的類都包含一個(gè)虛表。?
當(dāng)一個(gè)類(B)繼承另一個(gè)類(A)時(shí),類B會(huì)繼承類A的函數(shù)的調(diào)用權(quán)。所以如果一個(gè)基類包含了虛函數(shù),那么其繼承類也可調(diào)用這些虛函數(shù),換句話說(shuō),一個(gè)類繼承了包含虛函數(shù)的基類,那么這個(gè)類也擁有自己的虛表。
來(lái)看以下的代碼。類A包含虛函數(shù)vfunc1,vfunc2,由于類A包含虛函數(shù),故類A擁有一個(gè)虛表。
class A {
public:virtual void vfunc1(){ cout << "A::vfunc1" << endl;}virtual void vfunc2(){ cout << "A::vfunc2" << endl;}void func1();void func2();
private:int m_data1, m_data2;
};
類A的虛表如圖1所示。?
?虛表是一個(gè)指針數(shù)組,其元素是虛函數(shù)的指針,每個(gè)元素對(duì)應(yīng)一個(gè)虛函數(shù)的函數(shù)指針。需要指出的是,普通的函數(shù)即非虛函數(shù),其調(diào)用并不需要經(jīng)過(guò)虛表,所以虛表的元素并不包括普通函數(shù)的函數(shù)指針。
虛函數(shù)指針的賦值發(fā)生在編譯器的編譯階段,也就是說(shuō)在代碼的編譯階段,虛表就可以構(gòu)造出來(lái)了。
虛表是屬于類的,而不是屬于某個(gè)具體的對(duì)象,一個(gè)類只需要一個(gè)虛表即可。同一個(gè)類的所有對(duì)象都使用同一個(gè)虛表。
虛表指針
為了指定對(duì)象的虛表,對(duì)象內(nèi)部包含一個(gè)虛表的指針,來(lái)指向自己所使用的虛表。為了讓每個(gè)包含虛表的類的對(duì)象都擁有一個(gè)虛表指針,編譯器在類中添加了一個(gè)指針,*__vptr,用來(lái)指向虛表。這樣,當(dāng)類的對(duì)象在創(chuàng)建時(shí)便擁有了這個(gè)指針,且這個(gè)指針的值會(huì)自動(dòng)被設(shè)置為指向類的虛表。
?上面指出,一個(gè)繼承類的基類如果包含虛函數(shù),那個(gè)這個(gè)繼承類也有擁有自己的虛表,故這個(gè)繼承類的對(duì)象也包含一個(gè)虛表指針,用來(lái)指向它的虛表。
虛函數(shù)表存儲(chǔ)位置
首先虛函數(shù)表存儲(chǔ)在只讀數(shù)據(jù)段(.rodata)、虛函數(shù)存儲(chǔ)在代碼段(.text)、虛表指針的存儲(chǔ)的位置與對(duì)象存儲(chǔ)的位置相同,可能在棧、也可能在堆或數(shù)據(jù)段等。
擴(kuò)展:
?
?