您的位置:首页 > 编程语言 > C语言/C++

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

2014-04-25 09:51 274 查看
http://hi.baidu.com/ctrlaltz/item/3417b3aa4db3acf514329b51

一 多重继承

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到其他的父类的时候,需要做相应的指针的移动。

三 完!

感谢,Thanks!

作者:iTech

出处:http://itech.cnblogs.com/ 

转载:本文版权归作者iT
4000
ech所有,转载请注明出处,不得用于商业用途!

C++对象模型系列:

本系列是主要是作者经验的总结且同时参考了大量的网络文章,希望能够给C++的学习者有所帮助,但是由于作者水平有限,难免有错,希望大家能够指出,我将虚心地向大家学习,与大家共同进步!本系列的开发环境是Windows 32+VS2008。

文章:

指针和引用
指针与数组
指针与字符串
堆栈与函数调用
sizeof与对象内存布局
单继承与虚函数表
多重继承与虚函数表
虚继承与虚函数表
类型转化

#c++
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: