【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中的名称还是会在它 ...
随机推荐
- 20155207王雪纯 2006-2007-2 《Java程序设计》第1 周学习总结
20155207王雪纯 2006-2007-2 <Java程序设计>第1 周学习总结 教材学习内容总结 第一周重点学习第一章和第二章. 第一章总的来讲,我认为可以称之为本书的绪论,介绍了包 ...
- 20155233 2006-2007-2 《Java程序设计》第4周学习总结
20155233 2006-2007-2 <Java程序设计>第4周学习总结 教材学习内容总结 第六章: 继承:子类继承父类,避免重复的行为定义. extends关键词:继承并扩充行为. ...
- 20155332 如何获取新技能+c语言学习调查
如何获取新技能+c语言学习调查 你有什么技能比大多人(超过90%以上)更好? 如果问我有没有什么技能比大多数人,并且是90%的人好,我还真不敢说有,因为世界上有70亿人,要比63亿人做的好才行啊.我也 ...
- c++ 结束程序的几种方式
abort exit 一.用abort()结束程序 用abort()表示非正常结束程序.如果要正常结束程序得用exit() 二.用exit()结束程序 用exit()它可以使程序正常结束,这个函数 ...
- 【LG4148】简单题
[LG4148]简单题 题面 洛谷 题解 \(kdt\)模板题呀... #include <iostream> #include <cstdio> #include <c ...
- Linux中如何安装Apache服务器
Linux中如何安装Apache服务器 由于学习的需要,所有手动安装了一下Apache源码包,安装过程中的问题千奇百怪,但是如果弄清楚了问题出在哪里,那么也不是太难.如果有学习者出现安装中的问题,可仔 ...
- vue的ui库使用Element UI,纯html页面,不使用webpack那玩意
使用手册访问:https://cloud.tencent.com/developer/doc/1270 第一步:在head添加样式 <link rel="stylesheet" ...
- PHP原生代码写的微信扫码支付实例
一款PHP原生代码写的微信扫码支付,不基于任何框架,完全手写. 扫码支付只要授权域名对就OK,本地是无法测试.跟openid也没有关系,所以跟支付授权目录页没关系. 微信商户信息配置地址:weixin ...
- NO.04--我的使用心得之使用vue绑定class名
今天聊一聊这个话题,其实方式有很多种,我今天介绍几种我使用到的,各位看官耐心看: 一.用 变量形式 绑定单个 Class 名 在 vue 中绑定单个 class 名还好说,直接写就可以了 <te ...
- PHPCMS V9 的手机门户wap绑定单页面
当前的Phpcms V9手机网站的设置还有点弱,绑定的栏目不能设置选择模板,而且不能绑定单页面page.不过可以自定义做到绑定单页面page这一个功能:1.修改phpcms\modules\wap\i ...