日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

[C++对象模型][9]虚继承与虚函数表

發布時間:2025/3/13 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [C++对象模型][9]虚继承与虚函数表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一 虛繼承

1) 代碼:

Code
#include?<iostream>
using?namespace?std;

class?B
{
public:
????
int?i;
????
virtual?void?vB(){?cout?<<?"B::vB"?<<?endl;?}
????
void?fB(){?cout?<<?"B::fB"?<<?endl;}
};

class?D1?:?virtual?public?B
{
public:
????
int?x;
????
virtual?void?vD1(){?cout?<<?"D1::vD1"?<<?endl;?}
????
void?fD1(){?cout?<<?"D1::fD1"?<<?endl;}
};

class?D2?:?virtual?public?B
{
public:
????
int?y;
????
void?vB(){?cout?<<?"D2::vB"?<<?endl;}
????
virtual?void?vD2(){?cout?<<?"D2::vD2"?<<?endl;}
????
void?fD2(){?cout?<<?"D2::fD2"?<<?endl;}
};

class?GD?:??public?D1,?public?D2
{
public:
????
int?a;
????
void?vB(){?cout?<<?"GD::vB"?<<?endl;}
????
void?vD1(){cout?<<?"GD::vD1"?<<?endl;}
????
virtual?void?vGD(){cout?<<?"GD::vGD"?<<?endl;}
????
void?fGD(){cout?<<?"GD::fGD"?<<?endl;}
};

?

?

2)類圖:

?

3)VS2008的編譯選項查看布局:

?

4)可視化表示:

?

5)代碼驗證:(此時的虛函數表不是以NULL結尾,為什么?

Code
typedef?void?(*Fun)();

void?PrintMember(int?*pI)
{
????cout?
<<?*pI?<<?endl?<<?endl;
}
void?PrintVT(int?*pVT)
{
????
while(*pVT?!=?NULL)
????{
????????(
*(Fun*)(pVT))();
????????pVT
++;
????}
}

void?PrintMemberAndVT(GD?*pGD)
{
????
int?*pRoot?=?(int*)pGD;

????
int?*pD1VT?=?(int*)*(pRoot?+?0);?
????(
*(Fun*)(pD1VT))();?(*(Fun*)(pD1VT?+1))();
????
int?*pVB?=?(int*)*(pRoot?+1);??cout?<<?"vbtable's?adress:"?<<?*pVB?<<?endl;
????
int?*pX?=?(pRoot?+?2);?PrintMember(pX);

????
int?*pD2VT?=?(int*)*(pRoot?+?3);?
????(
*(Fun*)(pD2VT))();
????
int?*pVB2?=?(int*)*(pRoot?+4);?cout?<<?"vbtable's?adress:"?<<?*pVB2?<<?endl;
????
int?*pY?=?(pRoot?+?5);?PrintMember(pY);

????
int?*pA?=?(pRoot?+?6);?PrintMember(pA);

????
int?*pBVT?=?(int*)*(pRoot?+?7);?
????(
*(Fun*)(pBVT))();
????
int?*pI?=?(pRoot?+?8);?PrintMember(pI);
}

void?TestVT()
{
????B?
*pB?=?new?GD();
????GD?
*pGD?=?dynamic_cast<GD*>(pB);
????pGD
->i?=?10;
????pGD
->x?=?20;
????pGD
->y?=?30;
????pGD
->a?=?40;
????PrintMemberAndVT(pGD);
????delete?pGD;
}

?

6)驗證代碼結果:

?

7)總結:

虛繼承,使公共的基類在子類中只有一份,我們看到虛繼承在多重繼承的基礎上多了vbtable來存儲到公共基類的偏移。

?

二 虛繼承運行時類型轉化

?

1)代碼驗證:

?

Code
void?TestDynamicCast()
{
????B?
*pB?=?new?GD();
????GD?
*pGD?=?dynamic_cast<GD*>(pB);
????cout?
<<?"GD:"?<<?pGD?<<?endl;
????D1?
*pD1?=?dynamic_cast<D1*>(pB);
????cout?
<<?"D1:"?<<?pD1?<<?endl;
????D2?
*pD2?=?dynamic_cast<D2*>(pB);
????cout?
<<?"D2:"?<<?pD2?<<?endl;
????cout?
<<?"B:"?<<?pB?<<?endl;
}

?

?

2)驗證代碼結果:

?

3)總結:

還是從內存布局來看dynamic_cast時地址的變化,第一個基類的地址與子類相同,其他的基類和虛基類需要做偏移。

三 完!

轉載于:https://www.cnblogs.com/itech/archive/2009/03/01/1399996.html

總結

以上是生活随笔為你收集整理的[C++对象模型][9]虚继承与虚函数表的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。