记录: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++内存分 ...
随机推荐
- 关于css盒子模型和BFC的理解
CSS盒子模型 包含元素内容(content).内边距(padding).边框(border).外边距(margin) 一般元素总宽度 = element的width+padding的左右边距+mar ...
- 自定义类在PropertyGrid上的展示方法
自定义类在PropertyGrid上的展示方法 零.引言 PropertyGrid用来显示某一对象的属性,但是并不是所有的属性都能编辑,基本数据类型(int, double等)和.Net一些封装的类型 ...
- tyflow车撞墙测试
- [LeetCode] Car Fleet 车队
N cars are going to the same destination along a one lane road. The destination is target miles awa ...
- Linux shell编程 -test
test 命令的格式非常简单 test condition condition 是test命令要测试的一系列参数和值.当用在if-then 语句中时,test 命令看起来是这样的 if test co ...
- Best Cow Line---POJ 3617(贪心)
FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competiti ...
- cmd 创建用户,并授权管理员权限就可以远程登陆了
创建账号 net user 用户名 密码 /add //注意空格 授权管理员权限 net localgroup Administrators 用户名 /add // ...
- git 本地同步分支数,删除远程已经删除掉的多余分支
git remote show orgin (展示当前本地分支和远程上的分支差异,多余分支后会被标注 use 'git remote prune' to remove.) git remote pr ...
- 完整的系统帮助类Utils
//来源:http://www.cnblogs.com/yuangang/p/5477324.html using System; using System.Collections.Generic; ...
- 虚拟机桥接模式联网方法,Xshell的连接与使用
1.虚拟机的编辑中的虚拟网络编译器,新建一个VMnet0,选择桥接模式,选择上网时的网卡. 2.虚拟机 -> 设置 -> 网络适配器,选择启动时连接,桥接模式,复制物理网络连接状态. 3. ...