记录:C++类内存分布(虚继承与虚函数)
工具:VS2013
先说一下VS环境下查看类内存分布的方法:


先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1 reportSingleClassLayoutXXX(XXX为类名),则只会打出指定类XXX的内存布局。
编译后,输出如图的内存布局:

测试代码
#include <iostream>
using namespace std;
typedef void(*FUN)();
class A{
public:
int a;
virtual void print(){}
virtual void print_a(){
cout << "print_a()" << endl;
}
};
class B : virtual public A{
public:
int b;
void print(){}
virtual void print_b(){
cout << "print_b()" << endl;
}
};
class C : virtual public A{
public:
int c;
void print(){}
virtual void print_c(){
cout << "print_c()" << endl;
}
};
class D : public B, public C{
public:
int d;
void print(){}
virtual void print_d(){
cout << "print_d()" << endl;
}
};
int main()
{
D derived;
FUN *pFun = (FUN*)((*(int*)(A*)(&derived) + 4));
(*pFun)();
system("Pause");
return 0;
}
对象内存分布
1> class A size(8):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> +---
1>
1> A::$vftable@:
1> | &A_meta
1> | 0
1> 0 | &A::print
1> 1 | &A::print_a
1>
1> A::print this adjustor: 0
1> A::print_a this adjustor: 0
1>
1>
1> class ?$is_error_code_enum@PBD size(1):
1> +---
1> | +--- (base class ?$integral_constant@_N$0A@)
1> | +---
1> +---
1>
1>
1>
1> class B size(20):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | b
1> +---
1> +--- (virtual base A)
1> 12 | {vfptr}
1> 16 | a
1> +---
1>
1> B::$vftable@B@:
1> | &B_meta
1> | 0
1> 0 | &B::print_b
1>
1> B::$vbtable@:
1> 0 | -4
1> 1 | 8 (Bd(B+4)A)
1>
1> B::$vftable@A@:
1> | -12
1> 0 | &B::print
1> 1 | &A::print_a
1>
1> B::print this adjustor: 12
1> B::print_b this adjustor: 0
1>
1> vbi: class offset o.vbptr o.vbte fVtorDisp
1> A 12 4 4 0
1>
1>
1> class C size(20):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | c
1> +---
1> +--- (virtual base A)
1> 12 | {vfptr}
1> 16 | a
1> +---
1>
1> C::$vftable@C@:
1> | &C_meta
1> | 0
1> 0 | &C::print_c
1>
1> C::$vbtable@:
1> 0 | -4
1> 1 | 8 (Cd(C+4)A)
1>
1> C::$vftable@A@:
1> | -12
1> 0 | &C::print
1> 1 | &A::print_a
1>
1> C::print this adjustor: 12
1> C::print_c this adjustor: 0
1>
1> vbi: class offset o.vbptr o.vbte fVtorDisp
1> A 12 4 4 0
1>
1>
1> class D size(36):
1> +---
1> | +--- (base class B)
1> 0 | | {vfptr}
1> 4 | | {vbptr}
1> 8 | | b
1> | +---
1> | +--- (base class C)
1> 12 | | {vfptr}
1> 16 | | {vbptr}
1> 20 | | c
1> | +---
1> 24 | d
1> +---
1> +--- (virtual base A)
1> 28 | {vfptr}
1> 32 | a
1> +---
1>
1> D::$vftable@B@:
1> | &D_meta
1> | 0
1> 0 | &B::print_b
1> 1 | &D::print_d
1>
1> D::$vftable@C@:
1> | -12
1> 0 | &C::print_c
1>
1> D::$vbtable@B@:
1> 0 | -4
1> 1 | 24 (Dd(B+4)A)
1>
1> D::$vbtable@C@:
1> 0 | -4
1> 1 | 12 (Dd(C+4)A)
1>
1> D::$vftable@A@:
1> | -28
1> 0 | &D::print
1> 1 | &A::print_a
1>
1> D::print this adjustor: 28
1> D::print_d this adjustor: 0
1>
1> vbi: class offset o.vbptr o.vbte fVtorDisp
1> A 28 4 4 0
运行结果

记录:C++类内存分布(虚继承与虚函数)的更多相关文章
- 【C++ Primer | 15】C++类内存分布
C++类内存分布 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 下面可以定义一个类,像下面这样: c ...
- 【转】C++类-内存分布
C++类内存分布 - 转载自Jerry19880126 - 博客园 的文章 在上面这篇文章的基础上做了些整理. 主要讨论了C++类对象的内存分布结构. 来看看编译器是怎么处理类成员内存分布的,特别是在 ...
- 【转】C++类内存分布
C++类内存分布 https://www.cnblogs.com/jerry19880126/p/3616999.html 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看 ...
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- C++多重继承分析——《虚继承实现原理(虚继承和虚函数)》
博客转载:https://blog.csdn.net/longlovefilm/article/details/80558879 一.虚继承和虚函数概念区分 虚继承和虚函数是完全无相关的两个概念. 虚 ...
- c++虚继承与虚函数
学习继承与多态时看到这两个概念,记录整理. 虚继承与虚函数都是用virtual关键字实现,虚继承为了防止多重继承,而虚函数为了实现多态. 是几个例子. 虚继承: class A{}; class B: ...
- C++浅析——继承类内存分布和虚析构函数
继承类研究 1. Code 1.1 Cbase, CTEST为基类,CTest2为其继承类,并重新申明了基类中的同名变量 class CBase { public: int Data; CBase() ...
- C++类内存分布
http://www.cnblogs.com/jerry19880126/p/3616999.html#undefined 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看 ...
- 转载:C++类内存分布
本文转自:http://www.cnblogs.com/jerry19880126/p/3616999.html,原文写的非常好,从中学到了虚继承的概念,也学会了用VS查看内存分布. 说下C++内存分 ...
随机推荐
- 登录RabbitMQ的方法
一:(运行RabbitMQ之前需要先打开docker 容器)打开相应的路径,在windows Powershell 管理员下打开 输入:docker-compose -f .\docker-compo ...
- 【记录】Windows 操作系统常用快捷命令
https://www.lifewire.com/command-line-commands-for-control-panel-applets-2626060 打印机 control pr ...
- SSIS - 11.For循环容器
一.For循环容器中的3个循环变量 For循环容器,类似于编程语言中的For,用于重复执行容器内的任务,直到条件返回为False.与编程语言类似,For循环容器也需要定义以下3种循环属性: 注: 必须 ...
- FCC(ES6写法) Map the Debris
返回一个数组,其内容是把原数组中对应元素的平均海拔转换成其对应的轨道周期. 原数组中会包含格式化的对象内容,像这样 {name: 'name', avgAlt: avgAlt}. 思路: 直接使用公式 ...
- [BlueZ] 2、使用bluetoothctl搜索、连接、配对、读写、使能notify蓝牙低功耗设备
星期三, 05. 九月 2018 02:03上午 - beautifulzzzz 1.前言 上一篇讲了如何编译安装BlueZ-5,本篇主要在于玩BlueZ,用命令行去操作BLE设备: [BlueZ] ...
- html5 postMessage 实现类似 sendMessage 的同步效果,支持跨域
实现一个客户端发送 “save 一个答案,在获取答案, 跨域的另一个页面中,回调返回”3“的场景. 客户端:请在 http://127.0.0.1/pk/index.html 打开 <html& ...
- 数据库sql常见优化方法
以前刚开始做项目的时候,开发经验尚浅,每次遇到查询比较慢时,项目经理就会问:是不是又用select * 了?查询条件有没有加索引?一语惊醒梦中人,赶紧检查..果然如此! 有时我们写sql语句时,没有考 ...
- Android OpenSL ES 开发:使用 OpenSL 播放 PCM 数据
OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能,低响应时间的音频功能实现方法. 这次是使用OpenSL ES来做一个音乐播放器,它能够播放m ...
- [Swift]LeetCode113. 路径总和 II | Path Sum II
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- [Swift]LeetCode867. 转置矩阵 | Transpose Matrix
Given a matrix A, return the transpose of A. The transpose of a matrix is the matrix flipped over it ...