【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中的名称还是会在它 ...
随机推荐
- Flex copy and paste
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx ...
- 20155302 实验三 敏捷开发与XP实践
20155302 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验内容及步骤 (一)编码标准 在IDEA中使用工具(Code->Reformate Code)把代码重 ...
- C#基础之反射
虽然还在学校读书,反射实际写的不多.但感觉反射在程序开发中用得还是挺多的,对我来说也是.NET中的一个难点.通过反射,我们可以在运行时获得.NET中的每一个类型的成员,这些类型包括类.结构.委托和枚举 ...
- OpenCV参考手册之Mat类详解
OpenCV参考手册之Mat类详解(一) OpenCV参考手册之Mat类详解(二) OpenCV参考手册之Mat类详解(三)
- python3工作环境部署+spyder3+jupyter notebook
1.python3安装 1)官网去下载python3.7版本,双击安装,只要注意勾选写到PATH就行,其它直接NEXT. 2)安装完成,CMD键入 python 回车,跳出python界面就是成功. ...
- 数据结构思维导图 Part1
刚刚结束数据结构的学习,在复习阶段,所以做来思维导图总结一下. 思维导图,顾名思义是应该有对思维有引导作用的,就像思维的整理术,然而想要学好什么,光看思维导图总是不够的. 树与图作为两个复杂非线性结构 ...
- Ajax在Django中的应用
一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传 ...
- Django模型层:单表操作
一 ORM简介 查询数据层次图解:如果操作mysql,ORM是在pymysq之上又进行了一层封装
- win10 Docker Toolbox 默认路径不能写问题
2018-8-30 这几天正学习docker,win10系统家庭版,未升级成专业版,只能安装Docker Toolbox来练习, 安装好后准备做个镜像,默认路径新建目录却提示不允许创建 由于Docke ...
- arduino蜂鸣器的使用
一:蜂鸣器的使用 控制要求:模拟救护车响声 实物连接图: 电路原理图: 控制代码: //智慧自动化2018.6.11 ;//设置控制蜂鸣器的数字IO脚 void setup() { pinMode(b ...