真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

1、帶有虛函數(shù)的類

十年建站經(jīng)驗, 成都網(wǎng)站建設(shè)、網(wǎng)站制作客戶的見證與正確選擇。創(chuàng)新互聯(lián)提供完善的營銷型網(wǎng)頁建站明細(xì)報價表。后期開發(fā)更加便捷高效,我們致力于追求更美、更快、更規(guī)范。

class Base
{
public:
                 virtual void FunTest1()
                {
                                cout << "Base::FunTest1()" << endl;
                }

                 virtual void FunTest2()
                {
                                cout << "Base::FunTest2()" << endl;
                }

                 int _data1;
};
int main()
{
                 Base b;
                b._data1 = 0x01;
                 return 0;
}

對象模型:

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

mian函數(shù)的反匯編:

如果類中沒有自己寫構(gòu)造函數(shù),并且含有虛函數(shù),那么編譯器就會合成一個缺省的構(gòu)造函數(shù)。

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

 

Base()的構(gòu)造函數(shù)分析:

1>在它的構(gòu)造函數(shù)中主要完成的是:在&b指向的那塊空間中,填寫了虛指針,

2>注意:虛表是編譯器在編譯和鏈接完成之后就已經(jīng)建立好的,在構(gòu)造函數(shù)中只是將虛表的地址填寫到對象的前4個字節(jié)。

3>虛表中虛函數(shù)地址的存放順序,是按照它在類中聲明的順序存放的。

4>虛表中最后的00 00 00 00 表示虛表結(jié)束(編譯器不同就不一定了)

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

vptr指向虛表:

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

對象模型:

先是虛函數(shù)指針,再是該類的數(shù)據(jù)成員

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

 

 

2、單繼承(派生類中沒有虛函數(shù)的覆蓋)

class Base
{
public:
virtual void FunTest1()
{cout<<"Base::FunTest1()"<

主要還是完成虛指針的填寫

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

在是Derive的構(gòu)造函數(shù):

派生類最后的對象模型為:如果派生類沒有對基類中的虛函數(shù)進(jìn)行重寫時,派生類中的虛表先是基類的虛函數(shù)地址,然后再加上自己的虛函數(shù)地址。虛函數(shù)地址的順序為在類中聲明的順序。

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

派生類中Base的虛表

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

 

 

3、單繼承(含有虛函數(shù)的覆蓋)

class Base
{
public:
                 virtual void FunTest1()
                {
                                cout << "Base::FunTest1()" << endl;
                }
                 virtual void FunTest2()
                {
                                cout << "Base::FunTest2()" << endl;
                }
                 int _data1;
};
class Derive :public Base
{
public:
                 virtual void FunTest1()//覆蓋基類中的FunTest1
                {
                                cout << "Derive::FunTest1()" << endl;
                }
                 virtual void FunTest3()
                {
                                cout << "Derive::FunTest3()" << endl;
                }
                 virtual void FunTest4()
                {
                                cout << "Derive::FunTest4()" << endl;
                }
                 int _data2;
};
typedef void (*VtbFun)();
void PrintVtable()
{
                cout << "Derive類的虛函數(shù)表: " << endl;
                 Derive d1;
                d1._data1 = 0x01;
                d1._data2 = 0x02;

                 int* pVTable = (int *)*(int*)&d1;
                 VtbFun FunTest = (VtbFun )*pVTable;
                 while (NULL != FunTest)
                {
                                FunTest();
                                cout << ( int*)FunTest << endl;
                                pVTable += 1;
                                FunTest = ( VtbFun)*pVTable;
                }
                cout << "虛表結(jié)束: " << endl;
}
int main()
{
                PrintVtable();
                 return 0;
}

派生類對象模型及虛表建立規(guī)則:先將基類的虛表搬移過來,若派生類對基類中的某個函數(shù)進(jìn)行了重寫,則會用派生類重寫的虛函數(shù)的地址替換掉虛表中相應(yīng)位置基類中虛函數(shù)的地址,替換完之后再將派生類自己的虛函數(shù)地址按照聲明的順序添加到虛表中

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

4、多繼承(沒有虛函數(shù)的覆蓋)

class Base
{
public:
                 virtual void FunTest1()
                {
                                cout << "Base::FunTest1()" << endl;
                }
                 virtual void FunTest2()
                {
                                cout << "Base::FunTest2()" << endl;
                }
                 int _data1;
};
class Base1
{
public:
                 virtual void FunTest3()
                {
                                cout << "Base1::FunTest3()" << endl;
                }
                 virtual void FunTest4()
                {
                                cout << "Base1::FunTest4()" << endl;
                }
                 int _data2;
};
class Derive :public Base, public Base1
{
public:
                 virtual void FunTest5()
                {
                                cout << "Derive::FunTest5()" << endl;
                }
                 int _data3;
};

typedef void (*VtbFun)();
void PrintVtable()
{
                cout << "Derive類的虛函數(shù)表: " << endl;
                 Derive d1;
                d1._data1 = 0x01;
                d1._data2 = 0x02;

                 int* pVTable = (int *)*(int*)&d1;
                 VtbFun FunTest = (VtbFun )*pVTable;
                 while (NULL != FunTest)
                {
                                FunTest();
                                cout << ( int*)FunTest << endl;
                                pVTable += 1;
                                FunTest = ( VtbFun)*pVTable;
                }
                cout << "虛表結(jié)束. " << endl;
}
int main()
{
                 Derive d;
                d._data1 = 0x01;
                d._data2 = 0x02;
                d._data3 = 0x03;
                PrintVtable();
                 return 0;
}

5、多繼承(含有虛函數(shù)的覆蓋)

class Base
{
public:
                 virtual void FunTest1()
                {
                                cout << "Base::FunTest1()" << endl;
                }
                 virtual void FunTest2()
                {
                                cout << "Base::FunTest2()" << endl;
                }
                 int _data1;
};
class Base1
{
public:
                 virtual void FunTest3()
                {
                                cout << "Base1::FunTest3()" << endl;
                }
                 virtual void FunTest4()
                {
                                cout << "Base1::FunTest4()" << endl;
                }
                 int _data2;
};
// 這次將繼承列表中 Base和Base1 的位置互換
class Derive :public Base1, public Base
{
public:
                 virtual void FunTest1()
                {
                                cout << "Derive::FunTest1()" << endl;
                }
                 virtual void FunTest3()
                {
                                cout << "Derive::FunTest3()" << endl;
                }
                 virtual void FunTest5()
                {
                                cout << "Derive::FunTest5()" << endl;
                }
                 int _data3;
};

typedef void (*VtbFun)();
void PrintVtable()
{
                cout << "Derive類的虛函數(shù)表: " << endl;
                 Derive d1;
                d1._data1 = 0x01;
                d1._data2 = 0x02;
                d1._data3 = 0x03;

                 int* pVTable = (int *)*(int*)&d1;
                 VtbFun FunTest = (VtbFun )*pVTable;
                 while (NULL != FunTest)
                {
                                FunTest();
                                cout << ( int*)FunTest << endl;
                                pVTable += 1;
                                FunTest = ( VtbFun)*pVTable;
                }
                cout << "虛表結(jié)束. " << endl;
}
int main()
{
                PrintVtable();
                 return 0;
}

  

此時派生類的對象模型和虛表的結(jié)構(gòu):

  派生類虛表建立過程:先建立和Base1相同的部分,在Derive中對FunTest3進(jìn)行了重寫,所以替換掉虛表中原來的Base1::FunTest3改為了Derive::FunTest3,為了提高訪問速度,將自己特有的虛函數(shù)加在第一份虛表的后面,建立Base虛表的過程與Base1相同。

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

6、虛擬繼承

class Base
{
public :
                 virtual void FunTest1()
                {
                                cout << "Base::FunTest1()" << endl;
                }
                 virtual void FunTest2()
                {
                                cout << "Base::FunTest2()" << endl;
                }
                 int _data1;
};
class Derive : virtual public Base
{
public :
                 virtual void FunTest3()
                {
                                cout << "Derive::FunTest3()" << endl;
                }
                 virtual void FunTest4()
                {
                                cout << "Derive::FunTest4()" << endl;
                }
                 int _data2;
};
typedef void (* VtbFun)();
void PrintVtable()
{
                cout << "Derive類的虛函數(shù)表: " << endl;
                 Derive d1;
                d1._data1 = 0x01;
                d1._data2 = 0x02;

                 int * pVTable = (int *)*( int*)&d1;
                 VtbFun FunTest = (VtbFun )*pVTable;
                 while (NULL != FunTest)
                {
                                FunTest();
                                cout << ( int *)FunTest << endl;
                                pVTable += 1;
                                FunTest = ( VtbFun )*pVTable;
                }
                cout << "虛表結(jié)束: " << endl;
}
int main()
{
                PrintVtable();
                 return 0;
}

C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)

 


文章標(biāo)題:C++里的繼承和多態(tài)(下)——單繼承、多繼承、菱形繼承(含虛擬函數(shù)的繼承)
URL地址:http://weahome.cn/article/geggce.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部