多重继承与虚函数表

 
FROM:  http://www.cnblogs.com/itech/archive/2009/02/28/1399995.html

一 多重继承

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)代码验证:
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();
*pD = dynamic_cast<D*>(pB1);
pD
->= 10;
pD
->= 20;
pD
->= 30;
pD
->= 40;
PrintVTAndMember(pD);
delete pD;
}
 
 

7)总结:

与单继承相同的是所有的虚函数都包含在虚函数表中,所不同的多重继承有多个虚函数表,当子类对父类的虚函数有重写时,子类的函数覆盖父类的函数在对应的虚函数位置,当子类有新的虚函数时,这些虚函数被加在第一个虚函数表的后面。

二 多重继承运行时类型转化

1)代码验证:

void TestDynamicCast()
{
B1 
*pB1 = new D();
cout 
<< "B1:" << pB1 << endl;
*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;
}

 
 

3)总结:

从多重继承的内存布局,我们可以看到子类新加入的虚函数被加到了第一个基类的虚函数表,所以当dynamic_cast的时候,子类和第一个基类的地址相同,不需要移动指针,但是当dynamic_cast到其他的父类的时候,需要做相应的指针的移动。

三 完!

感谢,Thanks!

作者:iTech
出处:http://itech.cnblogs.com/
转载:本文版权归作者iTech所有,转载请注明出处,不得用于商业用途!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值