Inside C++ object Model--对象模型概述

在C中, "数据"和"处理数据的操作"是分开声明的, 语言本身并没有支持"数据和函数"之间的关联性. 这种称为"procedural", 由一组算法函数所驱动, 他们处理的是共同的外部数据.

而C++, 则在程序风格, 更在程序的思考上有明显的差异, 它以ADT或class hierarchy的数据封装建立数据和操作的关联性. 在软件工程的眼光来看更为合理.

但是程序员往往出于效率和简易性考虑而选择C.

 

那么使用C++是否就一定意味着低效了...

其实C++在布局以及存储时间上的额外负担主要是由"virtual"引起的,

  • the virtual function mechanism in its support of an efficient run-time binding, and

  • a virtual base class in its support of a single, shared instance of a base class occurring multiple times within an inheritance hierarchy.

一般而言, 并没有什么天生的理由说C++一定比C庞大或迟缓.

 

对象模型

作为此书讨论的基础, 首先要来分析一下C++的对象模型. 所谓对象模型, 就是在内存中怎么样来存储一个对象.

对于对象的存储, 下面有3种模型

简单对象模型

这个模型, 顾名思义, 就是为了尽量减低C++编译器的设计复杂度而开发的, 当然简单带来的是空间和执行期的低效.

这个模型中, 对象就是一系列slots, slot中存放了指向members的指针, members按程序中的声明顺序排列.

对象中并不实际存放members, 只是存放member的指针, 这样的好处是member的类型不会影响对象的存储空间.

但是降低了访问效率,  和存储效率, 由于需要通过指针间接访问, 并要额外存储指针.

 

表格驱动对象模型

这个模型, 相对于简单模型, 更加抽象, 它会把data member和function member分别放在两个table中,

The member function table 和简单模型一样存放的是函数指针. The data member table 直接存放的是data本身.

而对象本身只存放这两个table的指针, 这样最大的好处是, 对象大小是固定的, 无论members怎样改变.

表格驱动对象模型

 

C++对象模型

C++模型从简单对象模型派生而来, 并对内存空间和存取时间做了优化. 各个member的存储方法如下,

Nonstatic data members are allocated directly within each class object.

Static data members are stored outside the individual class object.

Static and nonstatic function members are also hoisted outside the class object.

Virtual functions are supported in two steps:

  1. A table of pointers to virtual functions is generated for each class (this is called the virtual table ).

  2. A single pointer to the associated virtual table is inserted within each class object (traditionally, this has been called the vptr ).The type_info object associated with each class in support of runtime type identification (RTTI) is also addressed within the virtual table, usually within the table's first slot.

如下图所示, 对于C++对象模型, 对象内只会保存Nonstatic data members和vptr, 这个模型的优点是在于空间和存取时间的效率, 缺点是由于考虑存取效率把Nonstatic data members直接存放在对象中, 导致任何数据成员的改动都会影响类对象的大小. 此处表格驱动对象模型就提供了较大的弹性, 不过鱼和熊掌不能兼得. 在设计时, 就需要根据实际需要进行取舍, C++更看重效率, 而CORBA这样的组件平台, 就会选择耦合度更低的表格驱动模型, 以利于当类成员改变后, 可以不需重新编译客户代码(因为对于这种模型, 对象大小是不变的).

C++对象模型

继承的对象模型

前面讨论了基本的C++对象模型, 如果加入了继承语言特性, 对象模型又要做什么样的改动

这个问题就是怎样在内存中存放父类, 派生类, 以及建立之间的关系.

简单的想法就是, 在对象中增加一个slot去存放父类对象指针, 有几个父类就增加几个slots

更透明的方法是, 专门生成一个base class table来存放所有父类指针, 并在对象中增加一个bptr来指向这个table.

这个方法的问题就是由于间接性导致的效率问题, 但优点就是对象对于继承的一致的表现方式, 可以任意修改父类, 而不会影响该类对象本身

 

前面说了C++更看重效率, 所以它没有采用任何的间接方法,

The data members of the base class subobject are directly stored within the derived class object.

缺点很明显,就是任意base class发生改变, 所有用到该类的派生类都需要重新编译.

关于C++对于虚基类的处理会在后面章节讨论...



转载于:https://www.cnblogs.com/fxjwind/archive/2011/07/05/2098638.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/263389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Microsoft Visual C++ Runtime Library Runtime Error的解决的方法

打开浏览器时,出现Microsoft Visual C Runtime Library Runtime Error错误,初步预计是软件冲突,可能有多种出错的方式,我的是浏览器自己主动关闭。 一、 有些时候,在你安装、执行某个软件,可能会得到这样一…

java之hibernate之基于外键的一对一单向关联映射

这篇讲解基于外键的一对一单向关联映射 1.考察如下信息,人和身份证之间是一个一对一的关系。表的设计 注意:基于外键的一对一关联的表结构和多对一的表结构是一致的,但是,外键是唯一的。 2.类的结构 Person.java public class Per…

intellij idea 热部署 spring jvm 版

2019独角兽企业重金招聘Python工程师标准>>> 配置 intellij idea tomcat 加入下面这个参数, 对应jar 到 mvnrepo 下载 。 -javaagent:D:\work\springloaded-1.2.3.RELEASE.jar -noverify 转载于:https://my.oschina.net/u/556878/blog/416563

大数据——Hadoop学习笔记(配置)

具体代码可以参考: https://github.com/Ostrich5yw/java4BigData

以C#编写的Socket服务器的Android手机聊天室Demo

内容摘要 1.程序架构 2.通信协议 3.服务器源代码 4.客户端源代码 5.运行效果 一、程序架构 在开发一个聊天室程序时,我们可以使用Socket、Remoting、WCF这些具有双向通信的协议或框架。而现在,我正要实现一个C#语言作为服务器端、Android作为客户端的聊天…

maven环境快速搭建

2019独角兽企业重金招聘Python工程师标准>>> 最近,开发中要用到maven,所以对maven进行了简单的学习。因为有个maven高手在身边,所以,很快就上手了,我这里算是自我总结吧。关于maven是什么东东,请…

20190718考试70分记

又考试了&#xff0c;这次题明显感觉难多了&#xff0c;骗了不少分&#xff0c;竟然rk13 第一题一看不可做&#xff0c;然后看第二题 第二题一开始也没有思路&#xff0c;然后我就看上了k<1的情况&#xff0c; 显然k0时只要求所有数的gcd即可&#xff0c; k1的话枚举每一个树…

[散记]今天

前几天还下了一场不小的雪&#xff0c;冷的很。昨天出门还穿了厚毛衣和棉外套&#xff0c;起风的时候还觉得凉飕飕的。今天就热的很了&#xff0c;天气预报说最高温度有16度。出门换了薄毛衣和薄外套&#xff0c;走了一段路&#xff0c;竟是闷热的很&#xff0c;索性将外套脱掉…

火狐、IE浏览器实现Extjs的grid表格的复制、粘贴

2019独角兽企业重金招聘Python工程师标准>>> 从后台获取参数&#xff0c;一次填入ext&#xff1a;grid网状表格&#xff0c;发现表格内的数据不能复制粘贴&#xff0c;只能read...&#xff0c;火狐和IE 11都不能复制。 火狐解决方案 局部定义表格复制、粘贴的样式&a…

Form表单的主要Content-Type

在Spa单页面横行的时代&#xff0c;前后端交互基本都是Json交互&#xff08;也有通过FormData的&#xff0c;比如上传文件&#xff09;。而在之前的Jsp&#xff0c;Php前后不分家的时候&#xff0c;前后交互好大一部分都是通过Form表单来完成的。From标签个属性叫 enctype&…

perl子例程

2019独角兽企业重金招聘Python工程师标准>>> sub 子例程名($$)指定两个标量的参数 ($)指定一个数组 按引用调用 符号引用 typeglob 类似于UNIX文件系统中的软链接 星号(*)适用于任意类型的变量&#xff0c;包括标量&#xff0c;数组&#xff0c;散列&#xff0c;文件…

FormView在什么情况下自动生成模板项?

刚才在鼓捣GridView与FormView&#xff0c;记得前一段时间在做时&#xff0c;点击gridview中的一项会在formview中显示详细的数据&#xff0c;而在 formview中只有编写了ItemTemplate等模板才会显示&#xff0c;我清楚的记得上次我并没有手工去编写itemTemplate模板&#xff0c…

Java遍历Map的几种方式

方法一&#xff1a;使用lambda表达式 Map<Integer, Integer> temp new HashMap<>(); temp.put(1,1); temp.put(2,1); temp.put(3,1); temp.forEach((k, v) -> System.out.println(v));其中&#xff0c;k是键&#xff0c;v是值 运行结果&#xff1a; 方法二&…

Java使用数组作为Map的key

先说结论&#xff1a;Map使用数组作为key&#xff0c;存放的是其地址 我们用如下代码进行测试&#xff1a; 我们的本意是 将[‘a’,‘b’,‘c’]的字符数组存放入map且对应的value为1查询map中是否包含key为[‘a’,‘b’,‘c’]的键值对将[‘a’,‘b’,‘c’]的字符数组对应的…

电脑电视兼容成科技行业新课题

随著深受网民喜爱的网络娱乐节目层出不穷&#xff0c;科技行业一个尚未解决的问题被提上日程&#xff1a;发明让用户得以在电视机上随意收看网络节目的产品。眼下&#xff0c;微软(Microsoft Corp.)、苹果电脑(Apple Computer Inc.)和英特尔(Intel Corp.)等多家行业巨头正在紧锣…

LeetCode—49. 字母异位词分组

49. 字母异位词分组 题目描述&#xff1a; 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的字母得到的一个新单词&#xff0c;所有源单词中的字母通常恰好只用一次。 考察重点&#xff1a;转为…

移动web性能优化笔记

移动web性能优化 最近看了一些文章&#xff0c;对移动web性能优化方法&#xff0c;做一个简单笔记 笔记内容主要出自 移动H5前端性能优化指南和移动前端系列——移动页面性能优化 转载于:https://www.cnblogs.com/GongQi/p/4534392.html

mysql04

连接查询 连接方式 1.交叉连接&#xff1a;交叉连接是将两个表不设定任何条件的连接结果。这种方式会产出好多个无效行。所以不用。 2.内连接 语法 select * from tb_name join tb2_name on tb_name.idtb2_name.id(注意 两个id字段的值应该是相等的&#xff09; 3.外连接 左&am…

我想和你一起去这样一个地方

当我从网站看到这则图片,我不禁惊叹有这样一个世外桃源,可以这样漂亮这样水天一色,我是多渴望能够与深爱的人一起去这个地方,享受我们休闲的白天,度过我们浪漫的夜晚,就这样,我也愿意和你每天每夜呆在一起.当我看到这则相片的时候,我心里只想着他,想和他一起去度假,我很喜欢痴住…