一、前言

  在看了皓哥的C++对象的布局之后:http://blog.csdn.net/haoel/article/details/3081328。感觉自己还是总是不能记得很清楚,故在此总结一下C++对象的内存布局,一遍以后及时复习。

二、

  1. 单一非虚继承:有成员变量,有虚函数和虚函数的覆盖,不是虚拟继承

源码如下:

#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;
}
virtual void h()
{
cout << "Parent::g()" << endl;
}
}; class Child : public Parent
{
public:
int ichild;
Child() : ichild() {}
virtual void f()
{
cout << "Child::f()" << endl;
}
virtual void g_child()
{
cout << "Child::g_child()" << endl;
}
virtual void h_child()
{
cout << "Child::h_child()" << endl;
}
}; class GrandChild : public Child
{
public:
int igrandchild;
GrandChild() : igrandchild() {};
virtual void f()
{
cout << "GrandChild::f()" << endl;
}
virtual void g_child()
{
cout << "GrandChild::g_child()" << endl;
}
virtual void h_gradnchild()
{
cout << "GrandChild::h_grandchild()" << endl;
}
};
int main(int argc, char **argv)
{
GrandChild gc;
typedef void(*Fun)(void);
Fun pf; cout << "[0] GrandChild::vfptr->" << endl;
cout << " [0]";
pf = (Fun)*(int *)*(int *)&gc;
pf(); cout << " [1]";
pf = (Fun)*((int *)*(int *)&gc + );
pf(); cout << " [2]";
pf = (Fun)*((int *)*(int *)&gc + );
pf(); cout << " [3]";
pf = (Fun)*((int *)*(int *)&gc + );
pf(); cout << " [4]";
pf = (Fun)*((int *)*(int *)&gc + );
pf(); cout << " [5]";
pf = (Fun)*((int *)*(int *)&gc + );
pf(); cout << "[1] Parent.iparent = " << (int)(*((int *)&gc + )) << endl;
cout << "[2] Child.ichild = " << (int)(*((int *)&gc + )) << endl;
cout << "[3] GrandChild.igrandchild = " << (int)(*((int *)&gc + )) << endl;
return ;
}

代码运行结果如下:

[] GrandChild::vfptr->
[]GrandChild::f()
[]Parent::g()
[]Parent::g()
[]GrandChild::g_child()
[]Child::h_child()
[]GrandChild::h_grandchild()
[] Parent.iparent =
[] Child.ichild =
[] GrandChild.igrandchild =

由此可见,在这种继承关系下,一个对象会有一个被称作虚函数表指针的vfptr。接着会存放Parent -> Child -> GrandChild。这里直接把皓哥的图片拿来用了:

可以看出:1.虚函数表指针在整个对象的最前面;

     2.基类数据成员放在派生类的前面;

     3.在虚函数表中派生类覆盖的函数得到了更新。

sizeof(gc) = 16 : sizeof( vfptr ) + 3 * sizeof( int )

C++对象内存布局 (一)的更多相关文章

  1. 图说C++对象模型:对象内存布局详解

    0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看. 本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有 ...

  2. c++ 对象内存布局详解

    今天看了的,感觉需要了解对象内存的问题.参考:http://blog.jobbole.com/101583/ 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个 ...

  3. c++对象内存布局

    这篇文章我要简单地讲解下c++对象的内存布局,虽然已经有很多很好的文章,不过通过实现发现有些地方不同的编译器还是会有差别的,希望和大家交流. 在没有用到虚函数的时候,C++的对象内存布局和c语言的st ...

  4. c++对象内存布局的理解

    我对c++对象内存布局的理解   引言 结合网上的一些资料,通过自己的一番摸索,得出了一点个人见解.现在写下来,希望与各位同学共同探讨,共同进步. 以下所有代码均是在VS2012下测试. 一个普通的基 ...

  5. 好文章系列C/C++——图说C++对象模型:对象内存布局详解

    注:收藏好文章,得出自己的笔记,以查漏补缺!     ------>原文链接:http://blog.jobbole.com/101583/ 前言 本文可加深对C++对象的内存布局.虚表指针.虚 ...

  6. 使用sos查看.NET对象内存布局

    前面我们图解了.NET里各种对象的内存布局,我们再来从调试器和clr源码的角度来看一下对象的内存布局.我写了一个测试程序来加深对.net对象内存布局的了解: using System; using S ...

  7. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  8. 浅析GCC下C++多重继承 & 虚拟继承的对象内存布局

    继承是C++作为OOD程序设计语言的三大特征(封装,继承,多态)之一,单一非多态继承是比较好理解的,本文主要讲解GCC环境下的多重继承和虚拟继承的对象内存布局. 一.多重继承 先看几个类的定义: 01 ...

  9. C++对象内存布局测试总结

    C++对象内存布局测试总结 http://hi.baidu.com/����/blog/item/826d38ff13c32e3a5d6008e8.html 上文是半年前对虚函数.虚拟继承的理解.可能 ...

  10. C++对象内存布局 (二)

    在上一篇文章中讨论了C++单一一般继承的对象内存布局http://www.cnblogs.com/uangyy/p/4621561.html 接下来继续讨论第二种情况: 2.单一的虚拟继承:有成员变量 ...

随机推荐

  1. wordpress 你所不知道的固定链接设置方法,设置适合自己的个性固定链接,适合SEO

    %year% 年份,四位数字,例如2004年  %monthnum% 一年的月份,例如05  %day% 一个月的日子,例如28  %hour% 一天中的小时,例如15  %minute% 小时,例如 ...

  2. Javascript实现导航锚点滚动效果实例

    本篇文章主要介绍了Javascript实现页面滚动时导航智能定位,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 常见的开发页面中可能会有这么一个需求,页面中会有多个模块,每个模块对应一个导航,当页 ...

  3. JS——设置cookie

    cookie 用来识别用户. <html> <head> <script type="text/javascript"> function ge ...

  4. Java中File对象的常用方法

    创建: 1.createNewFile()指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false. 2.mkdir() 在指定位置创建一个单级文件夹. 3.mkdirs() ...

  5. 【原】Pchart生成图片

    学习网址: http://wiki.pchart.net/doc.introduction.html http://pchart.sourceforge.net/index.php

  6. DOM节点的获取

      document.getElementById();//id名,在实际开发中较少使用,选择器中多用class  id一般只用在顶级层存在 不能太过依赖id document.getElements ...

  7. 00.用 yield 实现 Python 协程

    来源:Python与数据分析 链接: https://mp.weixin.qq.com/s/GrU6C-x4K0WBNPYNJBCrMw 什么是协程 引用官方的说法: 协程是一种用户态的轻量级线程,协 ...

  8. hdu 5174 Ferries Wheel

    摩天轮是一个环,周围围绕着一些缆车.每个缆车按顺序编号为1,2,3...K-1,K1,2,3...K−1,K而且每个缆车也拥有一个唯一的值且保证A[i-1] < A[i] < A[i+1] ...

  9. 绿色地址栏扩展验证(EV)SSL证书、支持SGC 强制最低128位

      Pro With EV SSL证书,最严格的域名所有权和企业身份信息验证,属于最高信任级别.最高安全级别的 EV SSL证书,该证书可以使地址栏变成高安全绿色,并且在地址栏内显示您公司的名称,提高 ...

  10. 清北学堂模拟赛d4t2 b

    分析:比较复杂的一题. 首先要求k个mod m互不相同且和为n的数ai,我们可以转化为求和为k个bi,并且(Σbi) % m = n % m 其中bi=ai % m,接下来可以用dp求出选了i个b,和 ...