前言中的内容:

  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继承”可以完成这项任务:  

    

 1 class Bear: public ZooAnimal {
 2 public:
 3     Bear();
 4     ~Bear();
 5     //...
 6     void rotate();
 7     virtual void dance();
 8     //...
 9 protected:
10     enum Dances{...};
11
12     Dance dances_known;
13     int cell_block;
14 };
15
16 Bear b("Yogi");
17 Bear *pb = &b;
18 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

  

  

转载于:https://www.cnblogs.com/vincently/p/4644099.html

【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)相关推荐

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

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

  2. 深度探索c++对象模型读书笔记:Data语意学-Data Member的绑定

    一个inline函数实体,在整个class声明未被完全看见之前,是不会被评估求值(evaluated)的,也就是说,对于如下代码: 1 extern int x; 2 3 class A 4 { 5 ...

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

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

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

    来源:http://dsqiu.iteye.com/blog/1669614 之前一直对C++内部的原理的完全空白,然后找到<Inside The C++ Object Model>这本书 ...

  5. 深度探索C++ 对象模型(2)-类的对象的内存大小_2

    继续上文,看看继承类的大小 1. Bear类 类对象的大小为24: 16+8 class Bear : public ZooAnimal { public:Bear() {};~Bear() {}; ...

  6. 深度探索C++ 对象模型(2)-类的对象的内存大小

    1. Question: 32bit机器 1个指向地址1000的指针的大小是多少? 指针类型 涵盖地址空间 整数指针 1000~1003(32bit整数是4-bytes) void*指针 不确定 2. ...

  7. 《Android深度探索卷一》读书笔记六

    1.简介 ARM架构的开发板基于X86架构的PC在CPU指令以及二进制格式上都有所不同.如果Linux驱动需要访问硬件(如LCD .WIFI,蓝牙等),这些硬件很难在PC上进行模拟,就要在带有这些硬件 ...

  8. 深度探索C++对象模型 学习笔记 第二章 构造函数语意学

    很多人抱怨说C++背着程序员做了太多事,如: if (cin) { /* ... */ } 为了让cin能转换为真假值,为cin定义一个类型转换运算符operator int(),就可以完成以上工作了 ...

  9. 《深度探索C++对象模型》--1 关于对象

    1.封装成本 与C比较,在virtual没有参与的情况下,C++的封装没有增加成本.C++在布局以及存取时间上的主要而外负担是由virtual引起的.包括:virtual function机制和vir ...

  10. 深度探索C++对象模型第2章 构造函数语义学

    默认构造函数 两个误区: 1 任何class如果没有定义默认构造函数,就会被合成一个出来:只有在某些情况下被合成 2 编译器合成出来的默认构造函数会明确设定class中每一个数据成员的默认值 :默认值 ...

最新文章

  1. TP 框架实现支付宝接口功能
  2. 一文读懂Serverless,配置化思想复用到平台系统中
  3. 騰訊大廈有39層的問題解決方案。
  4. 解决达梦数据库新增大字段报错问题
  5. boost::signals2模块实现连接类测试
  6. 16.1 用户变量语法
  7. 美一8岁华裔男童体育课上头部重伤 家长吁调查
  8. python怎样使用各个日期赤纬_python--日期操作
  9. 属性文法和语法制导翻译
  10. CI 图片上传路径问题的解决
  11. HDU 1017 A Mathematical Curiosity 数学题
  12. http 协议基本格式
  13. ubuntu下使用锐捷校园网
  14. 2019-2020新闻自动挂机阅读脚本应用开发
  15. 一款完全仿照E盾的源码(服务端+代理端+客户端)
  16. app消息推送接入流程
  17. UEditor之——图片上传组件大小4M的限制
  18. 360P2建html网站,360 P2路由器密码怎么设置?
  19. Java经典算法四十例编程详解+程序实例
  20. 笔记本高分屏字体模糊_高分屏软件字体模糊的参考解决办法

热门文章

  1. Dato for Mac(菜单栏时钟软件)
  2. FCPX安装插件位置及删除插件的方法
  3. Vue Document
  4. 数据分析为何能指导商业决策?
  5. 记centos7.2+上tomcat启动成功的监控脚本和nginx可配置多个域名
  6. PostgreSQL Server进程检查启动脚本
  7. [javase] 1.请从键盘随机输入10个整数保存到List中,并按倒序、从大到小的顺序显示出来...
  8. angularjs学习:事件
  9. [非原创] 获取CPUID;
  10. 企业网络管理员如何有效封杀QQ