C++使用继承时子对象的内存布局

 

C++使用继承时子对象的内存布局

1 示例程序

class A
{
protected:
int a;
public:
A() : a(1) {} virtual void a1() {}
virtual void a2() {}
}; class B
{
protected:
int b;
public:
B() : b(2) {} virtual void b1() {}
virtual void b2() {}
}; class C : public A, public B
{
protected:
int c;
public:
C() : c(3) {} virtual void a1() {}
virtual void b1() {}
}; int _tmain(int argc, _TCHAR* argv[])
{
C *c = new C;
B *b = (B *)c; return 0;
}

类 A/B/C 之间的关系如下:

2 对象的内存布局

C *c = new C();

在上面这段代码中,对象 c 的内存布局如下:

低地址        
       
1. 虚表指针 –> &C::a1 &A::a2 .
2. A::a        
3. 虚表指针 –> &C::b1 &B::b2 .
4. B::b        
5. c::c        
       
高地址        

c 对象从低地址到高地址依次存储了:A 的虚表指针、A 的成员变量、B 的虚表指针、B 的成员变量、C 的成员变量。我们发现,虚函数表 A 中的 A::a1 函数被 C::a1 函数覆盖了,虚函数表 B 中 B::b1 函数被 C::b1 覆盖了,这是因为 C 重写了 a1 和 b1方法。这意味着通过 c 对象中的虚表指针调用 a1 或 b1 函数,只能够调用到 C 类中重写的方法。

C *c = new C;
c->b1(); B *b = c;
b->b1();

上面的两句调用都会调用 C 的 b1 方法。另外,在对 b 赋值时,b 得到的结果并不是 c 的值,而是 c+8,这正好是 c 对象中用于存储 B 虚表指针的地址。

Date: 2016-01-12T22:44+0800

Author: ruleless

Org version 7.9.3f with Emacs version 24

Validate XHTML 1.0

C++使用继承时子对象的内存布局的更多相关文章

  1. C++ 各种继承方式的类内存布局

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  2. 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。

    本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...

  3. C++学习笔记----4.5 C++继承时的对象内存模型

    推荐阅读:http://blog.csdn.net/randyjiawenjie/article/details/6693337 最近研究了一下,C++继承的内存对象模型.主要是读了读http://b ...

  4. C++对象在继承情况下的内存布局

    1,C++ 中继承是非常重要的一个特性,本节课研究在继承的情形下,C++ 的对象模 型又有什么不同: 2,继承对象模型(最简单的情况下): 1,在 C++ 编译器的内部类可以理解为结构体: 2,子类是 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Android Activity 四种启动模式

    task和back stack(任务和回退栈) 任务启动,task被加入到回退栈的栈顶,返回的时候回退栈的栈顶任务会被弹出,并被销毁,栈中的前一任务恢复运行,当activity销毁是,系统不会保留ac ...

  2. Tengine

    Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性. 外文名 Tengine 发起单位 淘宝网 基    础 Nginx 目    ...

  3. js数组中去除重复对象及去除空对象的方法

    (function(){//去除数组中重复对象 var unique = {}; arr.forEach(function(a){ unique[ JSON.stringify(a) ] = 1 }) ...

  4. Avalon接口协议

    Avalon接口协议 https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/manual/mnl_ava ...

  5. 15.6.2 Configuring the Merge Threshold for index pages[innodb]

    MERGE THRESHOLD 提供了可以合并相邻索引page的功能. 默认值是50 如果一个页中数据被删除或者更新减小,导致页中有空白部分,空白部分接近合并门槛的值,则会和相邻页合并, 但是两个pa ...

  6. C# 采用事务批量插入数据

    首先要构建一个实体类,注意实体类的属性和数据的列要一一对应,否则会报错. public class Animal { public string Name { get; set; } public i ...

  7. VS2010中没有ado.net entity data model实体数据模型这一选项-解决办法

    前提先安装VS2010 SP1包. 解决办法: 1.从VS2010的安装盘目录下面的WCU\EFTools找到ADONETEntityFrameworkTools_chs.msi和ADONETEnti ...

  8. jquery 之选择器

    一.基本: HTML代码: <p class="p1">p段落</p> <h class="h1">h标签</h> ...

  9. 自定义Java集合

    一.泛型 1.在JDK1.4以前,所有的集合元素全都按照Object来存储,拿出来还要进行强制转型.由于这样的做法有太多的缺点,容易出现ClassCaseException,不安全,让人不省心,于是乎 ...

  10. Generics and Collection (1)

    public static void main(String args[]) { List ints = Arrays.asList(), )}); ; for(Iterator it = ints. ...