日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

[C++对象模型][8]多重继承与虚函数表

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

一 多重繼承

1) 代碼:

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

class?B1
{
public:
????
int?x;
????
virtual?void?v1(){?cout?<<?"B1::v1"?<<?endl;?}
????
void?f1(){cout?<<?"B1::f1"?<<?endl;?}
};

class?B2
{
public:
????
int?y;
????
virtual?void?v2(){?cout?<<?"B2::v2"?<<?endl;?}
????
void?f2(){?cout?<<?"B2::f2"?<<?endl;?}
};

class?B3
{
public:
????
int?z;
????
virtual?void?v3(){?cout?<<?"B3::v3"?<<?endl;?}
????
void?f3(){?cout?<<?"B3::f3"?<<?endl;?}
};

class?D?:?public?B1,?public?B2,?public?B3
{
public:
????
int?a;
????
void?v3(){?cout?<<?"D::v3"?<<?endl;?}
????
virtual?void?vD(){?cout?<<?"D::vD"?<<?endl;?}
};

?

?

2)類圖:

?

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

?

4)可視化表示:

?

5)代碼驗證:

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

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

void?PrintVTAndMember(B1?*pD)
{
????
int?*pRoot?=?(int*)pD;
????
int?*pVTB1?=?(int*)*(pRoot?+?0);PrintVT(pVTB1);
????
int?*pMB1?=?pRoot?+1;?PrintMember(pMB1);
????
int?*pVTB2?=?(int*)*(pRoot?+?2);PrintVT(pVTB2);
????
int?*pMB2?=?pRoot?+3;?PrintMember(pMB2);
????
int?*pVTB3?=?(int*)*(pRoot?+?4);PrintVT(pVTB3);
????
int?*pMB3?=?pRoot?+5;?PrintMember(pMB3);
}

void?TestVT()
{
????B1?
*pB1?=?new?D();
????D?
*pD?=?dynamic_cast<D*>(pB1);
????pD
->x?=?10;
????pD
->y?=?20;
????pD
->z?=?30;
????pD
->a?=?40;
????PrintVTAndMember(pD);
????delete?pD;
}

?

?

6) 驗證代碼運行結果:

?

7)總結:

與單繼承相同的是所有的虛函數都包含在虛函數表中,所不同的多重繼承有多個虛函數表,當子類對父類的虛函數有重寫時,子類的函數覆蓋父類的函數在對應的虛函數位置,當子類有新的虛函數時,這些虛函數被加在第一個虛函數表的后面。

二 多重繼承運行時類型轉化

1)代碼驗證:

Code
void?TestDynamicCast()
{
????B1?
*pB1?=?new?D();
????cout?
<<?"B1:"?<<?pB1?<<?endl;
????D?
*pD?=?dynamic_cast<D*>(pB1);
????cout?
<<?"D:"<<?pD?<<?endl;
????B2?
*pB2?=?dynamic_cast<B2*>(pB1);
????cout?
<<?"B2:"?<<?pB2?<<?endl;
????B3?
*pB3?=?dynamic_cast<B3*>(pB1);
????cout?
<<?"B3:"?<<?pB3?<<?endl;
????delete?pD;
}

?

2)驗證代碼的運行結果:

?

3)總結:

從多重繼承的內存布局,我們可以看到子類新加入的虛函數被加到了第一個基類的虛函數表,所以當dynamic_cast的時候,子類和第一個基類的地址相同,不需要移動指針,但是當dynamic_cast到其他的父類的時候,需要做相應的指針的移動。

三 完!

轉載于:https://www.cnblogs.com/itech/archive/2009/02/28/1399995.html

總結

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

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