【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)
前言中的内容:
1.什么是C++对象模型?
1.语言中直接支持面向对象程序设计的部分
2. 对于各种支持的底层实现机制
2. C++ class的完整virtual functions在编译时期就固定下来了,程序员没有办法再执行器动态增加或取代其中一个。这使得虚拟调用操作得以快速地派送结果,付出的成本则是执行期的弹性。
3. 全局对象在main()函数之前便完成初始化。
第一章 关于对象
1. 在C++中,有两种class data members:static 和 nonstatic,以及三种class member functions: static, nonstatic和virtual。
2. C++对象模型:
Stroustrup当初设计(目前仍占优势)的C++对象模型是从简单对象模型派生而来的,并对内存空间和存取时间做了优化。在此模型中,Nonstatic data members 被配置于每一个class object之内, static data members则被放在个别的class object之外。Static和nonstatic function members也被放在个别的class object之外。Virtual functions则以两个步骤支持之:
1. 每一个class产生出一堆指向virtual functions的指针,放在表格之中。这个表格被称为virtual table(vtbl)。
2. 每一个class object被安插一个指针,指向相关的virtual table。通常这个指针被称为vptr。vptr的设定(setting)和重置(resetting)都由每一个class的constructor,destructor和copy assignment运算符自动完成。每一个clas所关联的type info object(用以支持 runtime type identification,RTTI)也经由virtual table被指出来,通常放在表格的第一个slot。
这个模型的主要优点在于它的空间和存取时间的效率;主要的缺点是如果应用程序代码本身未曾改变,但所用到的class objects的nonstatic data members有所改变(可能是增加、移除或更改),那么那些应用程序代码同样得重新编译。
3. C++多态
简单来说,接口的不同实现方式就是多态。同一操作作用于不同的对象,可以有不同的解释,产生不同的结果。
在C++,多态只存在于一个个的public class体系中。举个例子,指针px可能指向某个类型的object,或指向根据public继承关系派生而来的一个子类型(请不要把不良的转换操作考虑在内)。Nonpublic的派生行为以及类型为void *的指针可以说是多态的,但它们没有被语言明显地支持,也就是说他们必须由程序员通过显式的转换来管理。
C++以下列方法支持多态:
1. 经由一组隐式的转化操作。例如把一个derived class指针转化为一个指向其public class type的指针:
class circle: public shape{}
shape *ps = new circle()
2. 经由virtual function机制:
ps->func() 或 (*ps).func()
3. 经由dynamic_cast 和typeid运算符:
if (circle *pc= dynamic_cast<circle *>(ps))
在C++中,只有通过基类的指针或引用才能支持OO程序设计所需的多态性质。
4. 需要多少内存才能够表现一个class object?
一般而言要有:
1. 其nonstatic data members的总和大小
2. 加上任何aligement的需求而填补(padding)上去的空间(可能存在于members 之间,也可能存在于集合体边界)。
3.加上为了支持virtual而由内部产生的任何额外负担(overhead)
5. 指针的类型
一个指针,不管它指向哪一种数据类型,指针本身所需的内存大小是固定的。(32位4B, 64位8B)。“指向不同类型的指针”之间的差异,既不在其指针表示法不同,也不在其内容(代表一个地址)不同,而是在其所寻址出来的object类型不同。也就是说,“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小。
一个类型为void*的指针只能够持有一个地址,而不能够通过它操作所指之object。因为不知道它涵盖的地址空间。
加上多态之后:
现在,我们定义一个Bear,组为一种ZooAnimal,经由“public继承”可以完成这项任务:
class Bear: public ZooAnimal {
public:
Bear();
~Bear();
//...
void rotate();
virtual void dance();
//...
protected:
enum Dances{...};
Dance dances_known;
int cell_block;
};
Bear b("Yogi");
Bear *pb = &b;
Bear &rb = *pb;
b,pb,rb会有怎样的内存需求呢?不管是pointer或reference都只需要一个word的空间(在32为机器上是4-bytes)。Bear object需要24bytes,也就是ZooAnimal的16 bytes加上Bear所带来的8 bytes。
好,假设我们的Bear object放在地址1000处,一个Bear指针和一个ZooAnimal指针有何不同?
Bear b;
ZooAnimal *pz = &b;
Bear *pb = &b;
它们每个都指向Bear object的第一个byte(1000)。其间的差别是,pb所涵盖的地址包含整个Bear Object,而pz所涵盖的地址之包含Bear object中的ZooAnimal subject。
除了ZooAnimal subject中出现的members,你不能够试用pz来直接处理Bear的任何members。唯一例外是通过virtual机制:
//不合法:cell_lock不是ZooAnimal的一个member
//虽然我们知道pz目前指向一个Bear object
pz->cell_block;
//ok:经过一个显式的downcast操作就没有问题
(static_cast<Bear *>(pz))->cell_block;
//下面这样更好,但它是一个run—time operation
if(Bear* pb2 = dynamic_cast<Bear*>(pz))
pb2->cell_block;
//ok:因为cell_block是Bear的一个member。
pb->cell_block;
扩展阅读:
1.http://coolshell.cn/articles/9543.html
【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)的更多相关文章
- 【C++】深度探索C++对象模型读书笔记--Data语意学(The Semantics of data)
1. 一个空类的大小是1 byte.这是为了让这一类的两个对象得以在内存中配置独一无二的地址. 2. Nonstatic data member 放置的是“个别的class object”感兴趣的数据 ...
- 深度探索C++对象模型读书笔记(2)
以下测试平台均为vs 2012 指向Data Member的指针测试(1) #include <stdio.h> class Base1 { public: int val1; int v ...
- 【C++】深度探索C++对象模型读书笔记--执行期语意学(Runtime Semantics)
对象的构造和析构: 全局对象 C++程序中所有的global objects都被放置在程序的data segment中.如果显式指定给它一个值,此object将以此值为初值.否则object所配置到的 ...
- 【C++】深度探索C++对象模型读书笔记--构造函数语义学(The Semantics of constructors)(四)
成员们的初始化队伍(member Initia 有四种情况必须使用member initialization list: 1. 当初始化一个reference member时: 2. 当初始化一个co ...
- 深度探索C++对象模型读书笔记-第七章站在对象模型的尖端
Template 模板是在编译时期而非执行时期被计算的.因此其不会带来效率的降低. 1: const Point<float> &ref = 0; 该语句会实例化一个Point的f ...
- 深度探索C++对象模型读书笔记-第六章执行期语意学
在函数中,编译器会帮助将析构函数(Destructor) 安插在相应的位置.对于函数中的局部对象,会将析构函数安插在对象的每一个离开点. 例如: 1: void Function(int a) { 2 ...
- 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记
转载:http://dsqiu.iteye.com/blog/1669614 第一章 关于对象 使用class封装之后的布局成本: class并没有增加成本,data members直接内含在每一个c ...
- 深入探索C++对象模型 读书笔记
第1章 关于对象 1.C++在布局以及存取时间上的主要的额外负担是由virtual引起的,包括: a.virtual function机制,引入vptr以及vtbl,支持一个有效率的"执行期 ...
- 《深度探索C++对象模型》笔记——Data语意学
Data Member的绑定 inline member functin躯体之内的一个data member绑定操作会在整个class声明完成之后才发生. argument list中的名称还是会在它 ...
随机推荐
- 20155222卢梓杰 《Java程序设计》第1周学习总结
20155222 <Java程序设计>第1周学习总结 教材学习内容总结 JDK是一个工具程序,包括了JAVA程序语言,工具程序与JRE,JRE包括了部署技术,JAVA SE API 与 J ...
- 20155227 2016-2017-2《Java程序设计》课程总结
20155227 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:我眼中的师生关系. 预备作业2:一些简单的C语言知识回顾,并总结之前一些成功的 ...
- django使用流程
1.安装django包 (命令行)>pip install django # conda install django 2.安装成功后,可以新建django项目 1(命令行)>django ...
- 暗通道去雾算法的python实现
何凯明博士的去雾文章和算法实现已经漫天飞了,我今天也就不啰里啰唆,直接给出自己python实现的完整版本,全部才60多行代码,简单易懂,并有简要注释,去雾效果也很不错. 在这个python版本中,计算 ...
- Yii 2.0 Gridview源码分析
GridView yii\grid\GridView 作用:GridView是Yii中的一个Widget,用来展示数据表格.有排序,分页和过滤功能. GridView默认界面如下.这是用Gii生成的. ...
- 【MySQL函数】日期篇
1.date_format()函数 date_format(createtime,'%Y') 年 date_format(createtime,'%Y-%m') 年月 date_format(crea ...
- centos7下python3与python2共存并且开启py3虚拟环境
因为下载视频需要用到python3环境,今天在我的win上安装下载工具死活安装不上去,在大盘鸡上一下就安装成功了...可能在win上不兼容吧...无奈只能在大盘鸡上进行折腾了,顺便几个笔记 由于大盘鸡 ...
- equals和==方法比较(三)--Long中LongCache源码分析
下面我们来分析,上篇博客中遗留的问题,为什么下方的两个一个是true,两一个是false那? //true Long l1=123l; Long l2=123l; System.out.println ...
- SQL基本的45题
-- 查询Student表中的所有记录的Sname.Ssex和Class列.SELECT Sname,Ssex,Class from student -- 查询教师所有的单位即不重复的Depart列. ...
- Python爬虫:爬取美拍小姐姐视频
最近在写一个应用,需要收集微博上一些热门的视频,像这些小视频一般都来自秒拍,微拍,美拍和新浪视频,而且没有下载的选项,所以只能动脑想想办法了. 第一步 分析网页源码. 例如:http://video. ...