前言中的内容:

  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)的更多相关文章

  1. 【C++】深度探索C++对象模型读书笔记--Data语意学(The Semantics of data)

    1. 一个空类的大小是1 byte.这是为了让这一类的两个对象得以在内存中配置独一无二的地址. 2. Nonstatic data member 放置的是“个别的class object”感兴趣的数据 ...

  2. 深度探索C++对象模型读书笔记(2)

    以下测试平台均为vs 2012 指向Data Member的指针测试(1) #include <stdio.h> class Base1 { public: int val1; int v ...

  3. 【C++】深度探索C++对象模型读书笔记--执行期语意学(Runtime Semantics)

    对象的构造和析构: 全局对象 C++程序中所有的global objects都被放置在程序的data segment中.如果显式指定给它一个值,此object将以此值为初值.否则object所配置到的 ...

  4. 【C++】深度探索C++对象模型读书笔记--构造函数语义学(The Semantics of constructors)(四)

    成员们的初始化队伍(member Initia 有四种情况必须使用member initialization list: 1. 当初始化一个reference member时: 2. 当初始化一个co ...

  5. 深度探索C++对象模型读书笔记-第七章站在对象模型的尖端

    Template 模板是在编译时期而非执行时期被计算的.因此其不会带来效率的降低. 1: const Point<float> &ref = 0; 该语句会实例化一个Point的f ...

  6. 深度探索C++对象模型读书笔记-第六章执行期语意学

    在函数中,编译器会帮助将析构函数(Destructor) 安插在相应的位置.对于函数中的局部对象,会将析构函数安插在对象的每一个离开点. 例如: 1: void Function(int a) { 2 ...

  7. 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记

    转载:http://dsqiu.iteye.com/blog/1669614 第一章 关于对象 使用class封装之后的布局成本: class并没有增加成本,data members直接内含在每一个c ...

  8. 深入探索C++对象模型 读书笔记

    第1章 关于对象 1.C++在布局以及存取时间上的主要的额外负担是由virtual引起的,包括: a.virtual function机制,引入vptr以及vtbl,支持一个有效率的"执行期 ...

  9. 《深度探索C++对象模型》笔记——Data语意学

    Data Member的绑定 inline member functin躯体之内的一个data member绑定操作会在整个class声明完成之后才发生. argument list中的名称还是会在它 ...

随机推荐

  1. 20155220 2016-2017-2 《java程序设计》第二周学习总结

    教材学习内容总结 3.1类型.变量与运算符 1)基本类型 byte 字节型 1 byte short 短整型 2 bytes int 整型 4 bytes long 长整型 8 bytes float ...

  2. 20155233 《Java程序设计》 实验二 Java面向对象程序设计

    20155233 <Java程序设计> 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L ...

  3. 20145207《Java程序设计》实验一(Java开发环境的熟悉)实验报告

    <Java 程序设计>实验一(Java开发环境的熟悉)实验报告 目录 改变 Java开发环境的熟悉实验要求 实验成果 课后思考 改变 修改了之前仅仅是贴了图片,连代码都没粘的状态.增加了自 ...

  4. 【JUC源码解析】ConcurrentHashMap

    简介 支持并发的哈希表.其中包括红黑树,扩容,分槽计数等知识点. 源码分析 常量 private static final int MAXIMUM_CAPACITY = 1 << 30; ...

  5. golang 单元测试

    单元测试是质量保证十分重要的一环,好的单元测试不仅能及时地发现问题,更能够方便地调试,提高生产效率.所以很多人认为写单元测试是需要额外的时间,会降低生产效率,是对单元测试最大的偏见和误解. go 语言 ...

  6. vscode eslint格式化配置

    { // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsize &qu ...

  7. Cannot get connection for URL jdbc:oracle:thin:调用中无效参数

    这个报错明显是连接数据库的url没有写对,但是,我要说的是但是,同样的代码生产没有问题,而测试环境报错了.最终哥找到那个错误,jdbc连接数据库时,有ResultSet,PreparedStateme ...

  8. Eclipse与MySQL数据库连接步骤

    将Eclipse与数据库进行连接的步骤: 1. 下载并配置MySQL 2. 为新建的项目配置mysql的jar包(jdbc和connection的配置) a) 可直接引用外部文件(不建议做,这样项目一 ...

  9. linux 下 python 安装 Django

    安装 setuptools 使用easy_install命令 easy_install django

  10. 面向 Unity* 软件和虚拟现实的优化:运行时生成内容

    优化游戏以实现高性能一直是游戏开发过程中的一个重要因素.虽然开发人员一直尝试将硬件推向极致,但当移动游戏成为主流时,优化技术变得尤为突出.Unity* 软件.Unreal* 等常见引擎最初都是面向 P ...