91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-07-25 13:07:35 來源:網絡 閱讀:959 作者:夏初丶 欄目:編程語言

1、帶有虛函數的類

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++里的繼承和多態(下)——單繼承、多繼承、菱形繼承(含虛擬函數的繼承)

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

mian函數的反匯編:

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

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

 

Base()的構造函數分析:

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

2>注意:虛表是編譯器在編譯和鏈接完成之后就已經建立好的,在構造函數中只是將虛表的地址填寫到對象的前4個字節。

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

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

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

vptr指向虛表:

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

對象模型:

先是虛函數指針,再是該類的數據成員

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

 

 


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

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 FunTest3()
{cout<<"Derive::FunTest3()"<<endl;}
 
virtual void FunTest4()
{cout<<"Derive::FunTest4()"<<endl;}
 int _data2;
}; 
// 打印虛表
typedef void (*VtbFun)();
void PrintVtable()
{
cout<<"Derive類的虛函數表: "<<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<<"虛表結束: "<<endl;
}
int main()
{
Base b1;
Derive d1;
return 0;
}

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

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

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

在是Derive的構造函數:

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

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

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

派生類中Base的虛表

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

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

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

 

 


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

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類的虛函數表: " << 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 << "虛表結束: " << endl;
}
int main()
{
                PrintVtable();
                 return 0;
}

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

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

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

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類的虛函數表: " << 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 << "虛表結束. " << endl;
}
int main()
{
                 Derive d;
                d._data1 = 0x01;
                d._data2 = 0x02;
                d._data3 = 0x03;
                PrintVtable();
                 return 0;
}

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

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類的虛函數表: " << 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 << "虛表結束. " << endl;
}
int main()
{
                PrintVtable();
                 return 0;
}

  

此時派生類的對象模型和虛表的結構:

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

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

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類的虛函數表: " << 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 << "虛表結束: " << endl;
}
int main()
{
                PrintVtable();
                 return 0;
}

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

 

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

文昌市| 高雄县| 中阳县| 岑溪市| 杭州市| 盘山县| 灵川县| 绥中县| 鹤壁市| 易门县| 永定县| 大英县| 保定市| 汝阳县| 腾冲县| 兴义市| 高雄市| 平谷区| 文成县| 高青县| 册亨县| 五华县| 县级市| 噶尔县| 思南县| 永顺县| 湖口县| 金山区| 错那县| 隆安县| 宿松县| 丰原市| 平舆县| 阳泉市| 冕宁县| 北票市| 南宁市| 秀山| 永丰县| 瓮安县| 汽车|