前言中的内容:

  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. 20155311《Java程序设计》实验五(网络编程与安全)实验报告

    20155311<Java程序设计>实验五(网络编程与安全)实验报告 一.实验内容及步骤 任务一: 编写MyBC.java实现中缀表达式转后缀表达式的功能 编写MyDC.java实现从上面 ...

  2. Week6课下作业

    课本练习p2.96 p2.97 浮点数 float 单精度浮点数(32位) double 双精度浮点数(64位) 练习对应书上内容P78--P81页 知识点是IEEE浮点表示 符号(sign):s决定 ...

  3. python3出现转码问题的总结

    对于此(类)问题: (1)出现UnicodeEncodeError –> 说明是Unicode编码时候的问题: (2) ‘gbk’ codec can’t encode character –& ...

  4. OpenStack入门篇(七)之认证服务Keystone

    一.Keystone的概述 Keystone是Openstack的组件之一,用于为Openstack家族中的其它组件成员提供统一的认证服务,包括身份验证,令牌的发放和校验,服务列表,用户权限的定义等. ...

  5. abp 关闭审计日志

    在WebProject.Web.Mvc项目中的Startup文件夹下中的WebProjectWebMvcModule.cs public override void PreInitialize() { ...

  6. HTTP 两种基本请求方法 GET和 POST的区别

    GET方法 1.GET交互方式是从服务器上获取数据,而并非修改数据,所以GET交互方式是安全的.就像数据库查询一样,从数据库查询数据,并不会影响数据库的数据信息,对数据库来说,也就是安全的.2.GET ...

  7. Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2) E. The Supersonic Rocket

    这道题比赛之后被重新加了几个case,很多人现在都过不了了 算法就是先求凸包,然后判断两个凸包相等 我们可以吧凸包序列化为两点距离和角度 角度如果直接拿向量的叉积是不对的,,因为钝角和锐角的叉积有可能 ...

  8. ZT-----用javascrip写一个区块链

    几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...

  9. 【Linux 运维】 date的使用

    date的使用 一.常用时间格式 #年.月.日 四位年大写,其余小写 [root@localhost ~]# date +%Y #长格式显示四位数年 [root@localhost ~]# date ...

  10. Java fluent风格(转载)

    转载:java Fluent风格 一.我们先写一个通常的,即不使用fluent风格 1.实体类 package com.xbq.demo.stu; /** * @ClassName: Student ...