C++多重继承虚表的内存分布
接前面虚表的内存分布,今天重点看多重继承的虚表内存分布,简单的说,继承几个类便有几个虚表,如下代码
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++多重继承虚表的内存分布的更多相关文章
- 【转】C++类-内存分布
C++类内存分布 - 转载自Jerry19880126 - 博客园 的文章 在上面这篇文章的基础上做了些整理. 主要讨论了C++类对象的内存分布结构. 来看看编译器是怎么处理类成员内存分布的,特别是在 ...
- C++类内存分布
http://www.cnblogs.com/jerry19880126/p/3616999.html#undefined 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看 ...
- C++ 类的内存分布
C++类内存分布 转自:http://www.cnblogs.com/jerry19880126/p/3616999.html 先写下总结,通过总结下面的例子,你就会明白总结了. 下面总结一下: ...
- 转载:C++类内存分布
本文转自:http://www.cnblogs.com/jerry19880126/p/3616999.html,原文写的非常好,从中学到了虚继承的概念,也学会了用VS查看内存分布. 说下C++内存分 ...
- 【C++ Primer | 15】C++类内存分布
C++类内存分布 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 下面可以定义一个类,像下面这样: c ...
- 【转】C++类内存分布
C++类内存分布 https://www.cnblogs.com/jerry19880126/p/3616999.html 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看 ...
- c++类内存分布解析
首先使用Visual Studio工具查看类的内存分布,如下: 先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内 ...
- C++类虚函数内存分布(这个 你必须懂)
转自:http://www.cnblogs.com/jerry19880126/p/3616999.html C++类内存分布 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来 ...
- 使用Visual Studio查看C++类内存分布
书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 工欲善其事,必先利其器,我们先用好Visual Stu ...
随机推荐
- 数据结构(线段树):NOI 2016 区间
[问题描述] [输入格式] [输出格式] [样例输入] 6 3 3 5 1 2 3 4 2 2 1 5 1 4 [样例输出] 2 [样例说明] [更多样例] 下载 [样例 2 输入输出] 见目录下的 ...
- 模板:强连通分量&2-sat
void Tarjan(int x){ low[x]=ID[x]=++tot; st[++top]=x;Inst[x]=true; for(int i=fir[x];i;i=nxt[i]) if(!I ...
- supesite 连 discuz 论坛记录
上一篇,网站supesite里 有 config.php 这里记录访问地址,到时候可以更改这里变更域名或者外网地址. 这里同样也是 下载discuz,解压,bbs 下的文件为有效的内容,放到supe ...
- 今天知道了一个 反向代理,是apache 的一个功能,这里记录一下
什么事情都需要自己 去弄,记住了这句话,不要以为 别人会来帮你 在 apache 的http.conf 文件中(去掉注释) LoadModule proxy_module modules/mod_pr ...
- poj3294 Life Forms(后缀数组)
[题目链接] http://poj.org/problem?id=3294 [题意] 多个字符串求出现超过R次的最长公共子串. [思路] 二分+划分height,判定一个组中是否包含不小于R个不同字符 ...
- [Locked] Count Univalue Subtrees
Count Univalue Subtrees Given a binary tree, count the number of uni-value subtrees. A Uni-value sub ...
- cannot be deleted directly via the port API: has device owner network:floatingip
- Selenium webdriver 操作IE浏览器
V1.0版本:直接新建WebDriver使用 import org.openqa.selenium.WebDriver; import org.openqa.selenium.ie.InternetE ...
- 使用python进行接口测试
最近在做接口测试,之前公司的方案是使用postman进行接口测试.但是伟大的墙导致我们只能用离线版postman..然后一个很长很长的接口列表,一个接一个的访问.我的天哪..所以萌生了一个想法,使用p ...
- 424. Longest Repeating Character Replacement
以最左边为开始,往右遍历,不一样的个数大于K的时候停止,回到第一个不一样的地方,以它为开始,继续.. 用QUEUE记录每次不一样的INDEX,以便下一个遍历开始, 从左往右,从右往左各来一次..加上各 ...