深入探索C++对象模型(1) 关于对象(思维导图)

通过上面整个关于对象的基础知识框架,我们来分析两个例子,看一下在内存中,对象究竟长什么样。
Demo1:C++对象模型的内存布局
class Point {
public:
Point( float xval );
virtual ~Point();
float x() const;
static int PointCount();
protected:
virtual ostream&
print( ostream &os ) const;
float _x;
static int _point_count;
]};
对于上面这个Point类,在内存中是怎么布置起来的呢?
- 我们将这个问题分为几个小问题,考虑篇幅,答案直接给在问题后面:
- 构造函数存放在什么位置?(答:类外或者类内,由构造函数的定义位置所决定)
- 析构函数存放在什么位置?(答:虚函数表中的一个表项指向,即指针指向)
- nonstatic member function,这里为x()函数,存放在什么位置?(答:由构造函数的定义位置所决定)
- static member function,这里为PointCount(),存放在什么位置?(答:类外)
- 虚函数放在什么位置?(答:虚函数表中的一个表项指向,即指针指向)
- nonstatic data member放在什么位置?(答:类内)
- static data member放在什么位置?(答:类外)
根据以上这些问题,我们可以给出如下的对象布局方式:

由此可见,对于虚函数来说,它们由一个虚函数表统一管理,而在对象中只存放指向该虚函数表的指针。
Demo2:子类的对象布局
在Demo1中,我们了解了一个对象在内存中是如何存放的,现在我们给它加上继承机制
即父类派生的子类的对象在内存中是如何布局的
看下面这段代码:
class ZooAnimal {
public:
ZooAnimal();
virtual ~ZooAnimal();
// ...
virtual void rotate();
protected:
int loc;
String name;
};
class Bear : public ZooAnimal {
public:
Bear();
~Bear();
// ...
void rotate();
virtual void dance();
//....
protected:
enum Dances { ... };
Dances dances_known;
int cell_block;
};
class Panda : public Panda {
// ........
};
这里使用了二层继承 ZooAnimal <--- Bear <--- Panda.
思考下面这段代码,在内存中的布局是怎样的呢?
{
ZooAnimal za; // 对象分配在栈上
ZooAnimal *pza; // 指针分配在栈上
Bear b; //对象分配在栈上
Panda *pp = new Panda // pp指针分配在栈上,对象new在堆中
pza = &b;
}
根据注释上所说,我们在内存中的相应的位置,按顺序设想一下该段代码执行后内存中栈和堆的布局情况:

这个图中并没有考虑栈和堆的增长方向不同的因素,所以这里也就不深究。
栈中发生了什么很容易看得出,我们着重看一下在堆中的Panda对象的内存分布:
发现Panda对象被分成了三个部分,Panda对象 = Panda对象自己的一部分+Bear对象部分(Bear对象部分 = Bear对象自己的一部分 +基类ZooAnimal部分)
在栈中的Bear对象也是同样的道理。
由此图,我们大致了解了子类在内存中的布局。
因此,父类和子类之间的类型转换,即多态的实现,就可以认为是指针的覆盖范围的变换,而对内存布局没有影响。
小结:
简单探讨了一下对象在内存中的布局问题,以及如果通过布局来实现继承和多态的。
如果不正确的地方欢迎指正。
参考资料:
《深入理解C++对象模型》
深入探索C++对象模型(1) 关于对象(思维导图)的更多相关文章
- C#-常用对象-思维导图
C#-常用对象-思维导图 链接:http://pan.baidu.com/s/1jHNgS78 密码:3i74 如有错误,请告知我!
- BOM对象思维导图
- Python--day26--面向对象思维导图
- JavaScript思维导图—Window对象
JavaScript思维导图-来自@王子墨http://julying.com/blog/the-features-of-javascript-language-summary-maps/
- javaSE_07Java中类和对象-封装特性-思维导图
思维导图看不清楚时: 1)可以将图片另存为图片,保存在本地来查看 : 2)右击在新标签中打开放大查看 (IE不支持,搜狗,360可以):
- [Java 并发] Java并发编程实践 思维导图 - 第四章 对象的组合
依据<Java并发编程实践>一书整理的思维导图. 第一部分: 第二部分:
- 精心整理「服务器Linux C/C++」 成长路程(附思维导图)
前言 我不是名校毕业,更没有大厂的背景,我只是一个毕业不到 2 年的普普通通的程序员,在摸爬滚打的工作这段时间里,深知了有一个「完整的知识体系」是非常重要的.当事人非常后悔没有在大学期间知道这个道理- ...
- 跟着9张思维导图学习Javascript
学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将 po 出我收集的 9 张 javascript 相关的思维导图(非原创). 思维导图小tips: 思维导图又叫心智图,是表达发射性思维的 ...
- 各种图(流程图,思维导图,UML,拓扑图,ER图)简介
来源于:http://www.cnblogs.com/jiqing9006/p/3344221.html 流程图 1.定义:流程图是对过程.算法.流程的一种图像表示,在技术设计.交流及商业简报等领域有 ...
- 一篇文章一张思维导图看懂Android学习最佳路线
一篇文章一张思维导图看懂Android学习最佳路线 先上一张android开发知识点学习路线图思维导图 Android学习路线从4个阶段来对Android的学习过程做一个全面的分析:Android初级 ...
随机推荐
- linux 和 windows 安装composer
在 Linux 和 Mac OS X 中可以运行如下命令: curl -sS https://getcomposer.org/installer | phpmv composer.phar /usr/ ...
- display:block、inline、inline-block的区别及应用案例
A.display:block就是将元素显示为块级元素. block元素的特点是: 1.总是在新行上开始: 2.高度,行高以及顶和底边距都可控制: 3.宽度缺省是它的容器的100%,除非设定一个宽度; ...
- unity 2018获取本地ip 问题,ipaddress
Network.Player.ipAddress这个API在Unity2018被移除了 用如下代码 using System.Net; using System.Net.NetworkInformat ...
- R语言 删除变量rm函数
变量可以通过使用 rm()函数来删除.下面我们删除变量var.3.然后再打印变量时出现异常错误. rm(var.3) print(var.3) 当上面的代码执行时,它产生以下结果: [1] " ...
- canvas的measureText()方法
做一个小动画的时候遇到了个问题,就是在给文字应用渐变色的时候,不知怎么设置渐变色的区域. 渐变依赖于定义时的区域,超出这个区域只有纯色,而不是渐变色. 所以要取得文字的宽度. 查了资料得知,canva ...
- HA_Ship Transcation Log 事务日志传送
环境准备: 虚拟机3台,INTER-DC, INTER-SQLA, INTER-SQLB 创建域帐户 INTER\MSSQLSERVER.SERVICE,INTER\AGENT.SERVICE,分别添 ...
- c#项目代码风格要求
代码风格没有正确与否,重要的是整齐划一,这是我拟的一份<.Net 项目代码风格要求>,供大家参考. 1. C# 代码风格要求 1.1注释 类型.属性.事件.方法.方法参数,根据需要添加注释 ...
- nodejs记录2——一行代码实现文件下载
主要使用fs模块的pipe方法,简单粗暴: import fs from "fs"; import path from 'path'; import request from 'r ...
- 二、spark SQL交互scala操作示例
一.安装spark spark SQL是spark的一个功能模块,所以我们事先要安装配置spark,参考: https://www.cnblogs.com/lay2017/p/10006935.htm ...
- 撩课-Java每天5道面试题第10天
撩课Java+系统架构 视频 点击开始学习 81.Servlet的会话机制? HTTP 是一种无状态协议, 这意味着每次客户端检索网页时, 都要单独打开一个服务器连接, 因此服务器不会记录下 先前客户 ...