C++对象内存布局 (二)
在上一篇文章中讨论了C++单一一般继承的对象内存布局http://www.cnblogs.com/uangyy/p/4621561.html
接下来继续讨论第二种情况:
2.单一的虚拟继承:有成员变量,有虚函数和虚函数的覆盖,虚拟继承。
我们假设下面这样一种继承关系

源码如下:
#include <iostream>
using namespace std; class Parent
{
public:
int iparent;
Parent() : iparent() {}
virtual void f()
{
cout << "Parent::f()" << endl;
}
virtual void g()
{
cout << "Parent::g()" << endl;
}
}; class Child : virtual public Parent
{
public:
int ichild;
Child() : ichild() {}
virtual void f()
{
cout << "Child::f()" << endl;
}
virtual void g_child()
{
cout << "Child::g_child()" << endl;
}
};
int main(int argc, char **argv)
{
Child c;
typedef void(*Fun)(void);
Fun pf; cout << "[0] Child::vfptr->" << endl;
cout << " [0] ";
pf = (Fun)*((int *)*(int *)&c + );
pf(); cout << " [0] 0x" << (Fun)*((int *)*(int *)&c + ) << endl; cout << "[1] Child::vbptr->" << endl;
cout << " [0] " << *((int *)*((int *)&c + ) + ) << endl; cout << " [1] " << *((int *)*((int *)&c + ) + ) << endl; cout << " [2] " << *((int *)*((int *)&c + ) + ) << endl; cout << "[2] Child.ichild = " << (int)*((int *)&c + ) << endl; cout << "[3] = 0x" << (int *)*((int *)&c + ) << endl; cout << "[4] Parent::vfptr->" << endl;
cout << " [0] ";
pf = (Fun)*((int *)*((int *)&c + ) + );
pf(); cout << " [1] ";
pf = (Fun)*((int *)*((int *)&c + ) + );
pf(); cout << " [2] 0x" << (Fun)*((int *)*((int *)&c +) + ) << endl; cout << "[5] Parent.iparent = " << (int)*((int *)&c + ) << endl;
return ;
}
代码运行结果如下:
[] Child::vfptr->
[] Child::g_child()
[] 0x00000000
[] Child::vbptr->
[] -
[]
[]
[] Child.ichild =
[] = 0x00000000
[] Parent::vfptr->
[] Child::f()
[] Parent::g()
[] 0x00000000
[] Parent.iparent =
下面是该对象的内存布局图:

由上图我们可以知道:
1.在虚拟继承关系下,派生类的对象会产生一个名为虚基类表指针的指针vbptr,里面存放的是基类在对象中的偏移地址(从1开始,0单元存放的不知道有什么用)
2.在这种关系先,被继承的基类放在最后面,首先放的是派生类的成员变量和虚函数表
3.存放的顺序为:派生类虚函数表指针 -> 虚基类表指针 -> 派生类的成员变量 -> NULL -> 基类虚函数表指针 -> 基类成员变量
sizeof(c) = 24 : 2 * sizeof(vfptr) + 2 * sizeof(int) + sizeof(vbptr) + sizeof(void *)
注意:1.在虚拟机城的继承关系下,派生类的对象会有一个虚基类表指针,占用4个字节;
2.在派生类和被虚拟继承的基类之间有一个空指针。
C++对象内存布局 (二)的更多相关文章
- 浅析GCC下C++多重继承 & 虚拟继承的对象内存布局
继承是C++作为OOD程序设计语言的三大特征(封装,继承,多态)之一,单一非多态继承是比较好理解的,本文主要讲解GCC环境下的多重继承和虚拟继承的对象内存布局. 一.多重继承 先看几个类的定义: 01 ...
- JVM-对象及对象内存布局
目录 前言 类与对象 对象类二分模型 对象 对象内存布局 JOL工具 对象头 Mark Word 类型句柄 对象头与锁膨胀 无锁 偏向锁 轻量级锁 重量级锁 重量级锁降级 实例数据 填充 对象生命周期 ...
- JVM 系列(4)一看就懂的对象内存布局
请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...
- 图说C++对象模型:对象内存布局详解
0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看. 本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有 ...
- c++ 对象内存布局详解
今天看了的,感觉需要了解对象内存的问题.参考:http://blog.jobbole.com/101583/ 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个 ...
- c++对象内存布局
这篇文章我要简单地讲解下c++对象的内存布局,虽然已经有很多很好的文章,不过通过实现发现有些地方不同的编译器还是会有差别的,希望和大家交流. 在没有用到虚函数的时候,C++的对象内存布局和c语言的st ...
- c++对象内存布局的理解
我对c++对象内存布局的理解 引言 结合网上的一些资料,通过自己的一番摸索,得出了一点个人见解.现在写下来,希望与各位同学共同探讨,共同进步. 以下所有代码均是在VS2012下测试. 一个普通的基 ...
- 好文章系列C/C++——图说C++对象模型:对象内存布局详解
注:收藏好文章,得出自己的笔记,以查漏补缺! ------>原文链接:http://blog.jobbole.com/101583/ 前言 本文可加深对C++对象的内存布局.虚表指针.虚 ...
- 使用sos查看.NET对象内存布局
前面我们图解了.NET里各种对象的内存布局,我们再来从调试器和clr源码的角度来看一下对象的内存布局.我写了一个测试程序来加深对.net对象内存布局的了解: using System; using S ...
随机推荐
- Android:用签名打包后微信分享失效
刚开始使用微信分享,申请的微信appid也可以在直接使用,分享成功! 当我使用自己的签名打包分享时却分享失败,一闪而过,好郁闷的说,为什么之前没有打包就可以,签名打包后就不可以了... 开始查找各种资 ...
- hdu3535题解
hdu3535:http://acm.hdu.edu.cn/showproblem.php?pid=3535 该题是非常全面的一道分组背包问题.其实理解了最多一个的分组背包问题,解题起来也是很简单的. ...
- H5 标签属性、input属性
高亮文字: 全部商品只要<mark>6.18</mark> 结果: 加拼音文字: <ruby>變<rt>bian</rt></ ...
- [Windows Server 2012] Filezilla安装方法
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:FileZ ...
- Sping装配之——自动装配
Sping从两个角度来实现自动化装配: 组件扫描(component scaning):spring会自动发现应用上下文中所创建的bean; 自动装配(autowiring):spring自动满足be ...
- 不抛异常的swap函数
namespace AStuff{ template<typename T> class A { public: void swap(A *other) { using std::swap ...
- uva 1587(Box UVA - 1587)
题目大意是给定6个数对,每个数对代表一个面的长和宽,判断这6个面是否能构成一个长方体. 这种题一看很复杂,但是只要不想多了实际上这就是一个水题... 首先说明一下判断的思路: 1.长方体是有三个对面的 ...
- shell 读取目录指定文件并截取拼接
shell脚本读取指定文件并拼接成指定的版本信息
- 单例模式的python实现
# 本实例主要介绍单例模式 # 1.什么是单例模式 # 1. 确保有且只有一个对象被创建 # 2. 为对象提供一个访问点,以使程序可以全局访问该对象 # 3. 控制共享资源的并行访问 # 2.单例模式 ...
- 从NLP任务中文本向量的降维问题,引出LSH(Locality Sensitive Hash 局部敏感哈希)算法及其思想的讨论
1. 引言 - 近似近邻搜索被提出所在的时代背景和挑战 0x1:从NN(Neighbor Search)说起 ANN的前身技术是NN(Neighbor Search),简单地说,最近邻检索就是根据数据 ...