接前面虚表的内存分布,今天重点看多重继承的虚表内存分布,简单的说,继承几个类便有几个虚表,如下代码

class Drive : public Base1, public Base2, public Base3 {
public:
virtual void fd() { cout << "Drive::fd" << endl; }
virtual void gd() { cout << "Drive::gd" << endl; }
};

则虚表有3个,如下图所示:

添加更多的测试代码:

// trytest.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" #include <WTypes.h>
#include < iostream > using namespace std; class Base1 {
virtual void f() { cout << "Base1::f" << endl; }
virtual void g() { cout << "Base1::g" << endl; }
}; class Base2 {
virtual void f() { cout << "Base2::f" << endl; }
virtual void g() { cout << "Base2::g" << endl; }
}; class Base3 {
virtual void f() { cout << "Base3::f" << endl; }
virtual void g() { cout << "Base3::g" << endl; }
}; class Drive : public Base1, public Base2, public Base3 {
public:
virtual void fd() { cout << "Drive::fd" << endl; }
virtual void gd() { cout << "Drive::gd" << endl; }
}; typedef void(*Fun)(void); int main() {
Drive objDrive;
cout << "Size is = " << sizeof(objDrive) << endl; Fun pFun = NULL; cout<<"sizeof(int)="<<sizeof(int)<<endl;
cout<<"sizeof(int*)="<<sizeof(int*)<<endl; // 调用Base1的第一个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
// 调用Base1的第二个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
cout << "Address of virtual pointer 1 " << (int*)(&objDrive + ) << endl;
cout << "Value at virtual pointer i.e. Address of virtual table "
<< (int*)*(int*)((int*)&objDrive + ) << endl;
cout << "Information about VTable 1" << endl;
cout << "Value at 1st entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl;
cout << "Value at 2nd entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl; // 调用Base2的第一个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
// 调用Base2的第二个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
cout << "Address of virtual pointer 2 " << (int*)((int*)&objDrive + ) << endl;
cout << "Value at virtual pointer i.e. Address of virtual table "
<< (int*)*(int*)((int*)&objDrive + ) << endl;
cout << "Information about VTable 2" << endl;
cout << "Value at 1st entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl;
cout << "Value at 2nd entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl; // 调用Base3的第一个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
// 调用Base3的第二个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
cout << "Address of virtual pointer 3 " << (int*)((int*)&objDrive + ) << endl;
cout << "Value at virtual pointer i.e. Address of virtual table "
<< (int*)*(int*)((int*)&objDrive + ) << endl;
cout << "Information about VTable 3" << endl;
cout << "Value at 1st entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl;
cout << "Value at 2nd entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl; // 调用派生类的第一个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
// 调用派生类的第二个虚函数
pFun = (Fun)*((int*)*(int*)((int*)&objDrive + ) + );
pFun();
cout << "Value at 3rd entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl;
cout << "Value at 4th entry of VTable "
<< (int*)*((int*)*(int*)((int*)&objDrive + ) + ) << endl; //明确多重继承中虚函数的内存位置
cout <<"Address at 1st entry of VTable "
<< (int*)*((int*)&objDrive + ) + << endl; cout <<"Address at 2nd entry of VTable "
<< (int*)*((int*)&objDrive + ) + << endl; cout <<"Address at 3rd entry of VTable "
<< (int*)*((int*)&objDrive + ) + << endl; cout <<"Address at 4th entry of VTable "
<< (int*)*((int*)&objDrive + ) + << endl; pFun = (Fun)*((int*)*((int*)&objDrive + ) + );
pFun(); pFun = (Fun)*((int*)*((int*)&objDrive + ) + );
pFun(); pFun = (Fun)*((int*)*((int*)&objDrive + ) + );
pFun(); pFun = (Fun)*((int*)*((int*)&objDrive + ) + );
pFun(); return ;
}

内存分布如下所示:

C++多重继承虚表的内存分布的更多相关文章

  1. 【转】C++类-内存分布

    C++类内存分布 - 转载自Jerry19880126 - 博客园 的文章 在上面这篇文章的基础上做了些整理. 主要讨论了C++类对象的内存分布结构. 来看看编译器是怎么处理类成员内存分布的,特别是在 ...

  2. C++类内存分布

    http://www.cnblogs.com/jerry19880126/p/3616999.html#undefined 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看 ...

  3. C++ 类的内存分布

    C++类内存分布 转自:http://www.cnblogs.com/jerry19880126/p/3616999.html   先写下总结,通过总结下面的例子,你就会明白总结了. 下面总结一下: ...

  4. 转载:C++类内存分布

    本文转自:http://www.cnblogs.com/jerry19880126/p/3616999.html,原文写的非常好,从中学到了虚继承的概念,也学会了用VS查看内存分布. 说下C++内存分 ...

  5. 【C++ Primer | 15】C++类内存分布

    C++类内存分布 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 下面可以定义一个类,像下面这样: c ...

  6. 【转】C++类内存分布

    C++类内存分布  https://www.cnblogs.com/jerry19880126/p/3616999.html 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看 ...

  7. c++类内存分布解析

    首先使用Visual Studio工具查看类的内存分布,如下: 先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内 ...

  8. C++类虚函数内存分布(这个 你必须懂)

    转自:http://www.cnblogs.com/jerry19880126/p/3616999.html C++类内存分布 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来 ...

  9. 使用Visual Studio查看C++类内存分布

    书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 工欲善其事,必先利其器,我们先用好Visual Stu ...

随机推荐

  1. BestCoder Round #52 (div.1)

    这周六BC和CF又差点打架,精力不够啊...结果打BC没起来,就看了一眼题跑了...今天早上补补吧,(因为今天晚上还要打UER= =) 先放官方题解: 1000 Victor and Machine ...

  2. P1894セチの祈り

    描述 在 Ninian 的花园里,有许多琼花,环绕着中间的凉亭.有 N 片琼花,组成一个环.Ninian 想在凉亭中发动 [セチの祈り] , 需要划分出三个区域的琼花,为了平均,要最大化面积最小的区域 ...

  3. 【模拟】NCPC 2014 D Dice Game

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1790 题目大意: 两个人,每个人有两个骰子,每个骰子可以等概率取[a,b],问哪个人两 ...

  4. 【最大流】BAPC2014 A Avoiding the Apocalypse (Codeforces GYM 100526)

    题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...

  5. 【链表】【模拟】Codeforces 706E Working routine

    题目链接: http://codeforces.com/problemset/problem/706/E 题目大意: 给一个N*M的矩阵,Q个操作,每次把两个同样大小的子矩阵交换,子矩阵左上角坐标分别 ...

  6. Delphi NativeXml用法攻略 转

    NativeXml可以在官网上下载,下载后将文件夹放在指定地方,打开DELPHI在其环境变量中引用NativeXml路径,然后在程序中引用NativeXml单元,我们就可以使用NativeXml了. ...

  7. HDOJ 2053 Switch Game

    Problem Description There are many lamps in a line. All of them are off at first. A series of operat ...

  8. CodeForces 588A

    题目链接: http://codeforces.com/problemset/problem/588/A 解题思路: 这个题目很简单, 就是前一天肉的价格比后面几天低还是高,如果是高的话,只要买当天份 ...

  9. 关闭ES动态创建type

    虽说ES的默认设置已经够我们使用了,但是总有些情景需要我们修改一些配置. 由于ES 2.*不能单独删除某个type,只能将整个index删除.这无疑非常让人苦恼. 所以我们需要关闭动态创建type以减 ...

  10. 一键安装lnmp脚本

    前段时间一直在找一个快速部署lnmp环境的方法,也没找着,就自己写了一个,结合网上的大神们的.我的方法是脚本结合源码包,很多依赖裤都是yum安装的,这都在脚本里面,需要的源码包我都下载好了,打包成压缩 ...