记录: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++内存分 ...
随机推荐
- 关于阿里云Centos7 Mailx发送邮件失败的处理
开始通过配置系统自带的mail 发送邮件 在其中一台服务器怎么都不行 /etc/mail.rc配置: set from="邮箱名" set smtp="smtp.163. ...
- mysql 水平分表
新建10张表,user_0,user_1,...user_9,方法不可串用,采用hash或取余法,获取要操作的表名,取值用对应存值的方法 1.hash取余法 public function part_ ...
- Jvm 内存模型 —— GC
一.Jvm 原理 二.Jvm 运行时数据区( Run-Time Data Areas ) (主要是关于 non-stack 区域的详细划分) 从上图可以清楚地看到:程序计数器.Jvm 栈.本地方法栈 ...
- LoadRunner(四)——深度了解LR相关功能
参考学习感谢:<精通软件性能测试与LoadRunner实战> 相关功能: 1 无工具情况下的性能测试 2性能测试工具LoadRunner的工作原理 3 VuGen应用介绍 4 协议的类型及 ...
- Python练手例子(11)
61.打印出杨辉三角形. #python3.7 from sys import stdout if __name__ == '__main__': a = [] for i in range(10): ...
- java:找出占用CPU资源最多的那个线程
linux环境下,当发现java进程占用CPU资源很高,且又要想更进一步查出哪一个java线程占用了CPU资源时,按照以下步骤进行查找: 1.先用top命令找出占用资源厉害的java进程id,如: 2 ...
- 在C++中,setw(int n)
setw(int n)用来控制输出间隔例如:cout<<'s'<<setw(8)<<'a'<<endl;则在屏幕显示s a //s与a之间 ...
- Revisiting Network Support for RDMA
重新审视RDMA的网络支持 本文为SIGCOMM 2018会议论文. 笔者翻译了该论文.由于时间仓促,且笔者英文能力有限,错误之处在所难免:欢迎读者批评指正. 本文及翻译版本仅用于学习使用.如果有任何 ...
- JAVA高性能I/O设计模式
Java中的IO方式 主要分为3种:BIO(同步阻塞).NIO(同步非阻塞)和AIO(异步非阻塞). BIO 同步阻塞模式.在JDK1.4以前,使用Java建立网络连接时,只能采用BIO方式,在服务器 ...
- 脚本语言丨Batch入门教程第四章:调用与传参
今天是Batch入门教程的最后一章内容:调用与传参.相信通过前面的学习,大家已经掌握了Windows Batch有关的基础知识和编程方法,以及利用Windows Batch建立初级的编程思维方式.今后 ...