第一章关于对象

  • c++在布局和存取时间的额外负担主要有virtual引起

    - virtual function:运行期动态绑定

    - virtual base class :base class多次出现在派生类中,但只有一个单一而被共享的实体(虚基类)



  • 对象模型

    • 简单模型:每一个地址slot指向一个成员

    • 表格模型:数据表和成员函数表

    1. 数据表包含数据本身
    2. 成员函数表包含指向每个成员函数的指针slot

  • 虚函数表

    • 每个class产生一堆指向virtual function的指针,,指针形成一个virtual function table;
    • 每一个class object 添加一个指向virtual function table 的指针vptr
    • 每一个class 关联一个type_info object由虚函数表指出

被指定的object在执行点之前是无法确定类型的,必须通过指针或者引用操作实现

  • c++支持多态的方式

    • 隐含转化操作,子类指针赋值给父类指针
    • virtual function
    • dynamic_cast 和 typeid
    • 基类定义接口,通过virtual function方式,在运行时确定object类型并执行相应操作
  • 继承后类及对象的内存布局

    • 继承关系

    • 内存布局

    • 虚函数表

第二章 构造函数

2.1 default constructor 的构建

  • 生成default constructor 的要素:

    - 含有member object 且member object 均有default constructor

    - class本身无任何constructor,则调用constructor 时编辑器将为class合成一个default constructor

    - 以member objects 在class 声明次序调用各个member object 的 default constructor

    如果derived class 拥有多个constructor 但是没有default constructor,编译器将扩张每一个consturctor,加入每一个必要的基类default constructor,但不会再合成default constructor
2.1.1“带有default constructor ”的base class :
  • 自动合成default constructor

    - class 声明(继承)一个virtual function

    - class 派生自一个继承串联,其中至少一个virtual base class
  • 自动合成过程

    • 产生一个virtual function table,内放class的virtual functions 地址
    • 每一个class object合成一个pointer(vptr)指向class 的virtual function table

      已定义constructor则扩展,未定义则合成default constructor, 保证正确初始化每一个class object 的vptr
2.1.2“带有一个virtual base class”的class
  • 在derived class object 的每一个virtual base class 中插入一个指向,经由pointer 和reference 存取virtual base class 的操作由这个指针完整(指向同一份内容)

    - 已定义constructor则扩展,未定义则合成default constructor, 保证允许每一个virtual base class 执行器存取操作
  • summary:合成 implicit nontrivial default constructor

    • 借用member object 或者 base class 的default constructor
    • 为每一个object 初始化virtual function机制 或者 virtual base机制
    • 除以上以外,如无任何声明constructor 则不会合成default constructor
  • 合成的default constructor 中只有base class objects 和member class objects 被初始化,其他nonstatic data member,指针,数组都不会自动初始化
  • 解析

    ``
  1. 不是任何class都会合成 deafault constructor,只有member object 或者 base class 有default constructor 时,或者需要初始化virtual function 机制和virtual base class 机制时,合成default constructor
  2. 编译器合成的default constructor 并不会明确初始化每一个data member值

    ``

2.2 copy constructor 的构建

  • 执行copy constructor的三种情况:

    - 赋值

    - 作为参数传递

    - 作为返回值
  • default memberwise initialization

    - 对于member data 逐一赋值

    - 对于member function 递归调用 memberwise initialization
  • 当class 不展现一个“bitewise copy semantics”(如下四种情况),需要合成copy constructor

    0. class 内包含一个member object 且后者(声明或者合成)copy constrctor 时

    1. class 继承一个base class 且后者(声明或者合成)copy constrctor 时

    2. class 声明至少一个virtual function时

    3. class 派生自一个继承串联,其中至少一个virtual base class

2.3 program transformation semantics

  • explicit initialization:直接逐位赋值member data
  • argument initialization:参数构造临时对象并copy constrcuct
  • copy construct and 返回引用

2.4 member initialization list

  • initial 时:= 操作符以arguement初始化对象时分为三步:1、以arguement 构造一个 临时对象,2、将临时对象copy给目标对象,3、销毁临时对象
  • 初始化顺序是由members声明次序决定的,不是由member list 顺序决定的;
  • member list 中初始化先于explicit assignment:即:之后的初始化先于{}内部member data的初始化或者赋值

    X::x(int v):j(v){i = j;}j 的初始化先于i的初始化

第三章 the semantaic of data

3.1 data member 绑定

- 局域绑定

3.2 data member layout

- 同一access session 按照声明顺序合并,静态成员不存在class 内部

3.3 data member 存取

- static data member
> 独立于class 之外,不论是继承virtual base class而来或者函数调用得到的static 都是直接存取,通过指针和通过对象存取是一样的
- nonstatic data member
> 通过指向对象的指针和对象访问一致的,当访问的member data是一个从virtual base class 继承而来的member时,指针访问在运行时才能确定
- 多重继承
![pointer实现:共享虚基类](http://odfcr7qs4.bkt.clouddn.com/IMG_0073.PNG)
![offset实现:共享虚基类](http://odfcr7qs4.bkt.clouddn.com/IMG_0074.PNG)
- 多重继承的数据布局
![](http://images2015.cnblogs.com/blog/900750/201702/900750-20170211192953869-280093158.png)
- 虚拟继承:
- 指针方式实现



- 虚函数表首项偏移指向虚基类

3.6 pointer to data member

* &Pointer::z   “取一个nonstaic data member,得到它在class 中的偏移量”
* &origin.z “取一个class object 的data menber地址, 得到member在内存中的真正地址”
* 继承层次越深,指针代码执行速度越慢

第四章 the semantics of function

4.1 member 调用方式

* nonstatic member function
〉 0. 安插this指针
1. 对nonstatic member function 经由this 指针存取
2. 将member function 改写成独一无二(name mangling)的外部函数
- nonstatic member function 与外部函数的访问性能是一样的
* virtual member function
> 经由对象调用virtual function 被处理为编译绑定,与nonstatic member function的调用方式一致
* static member function
> 0. 通过指针或者对象调用静态成员函数都被当做一般函数处理
〉 1. static member function 没有this 指针,被当做一般函数处理

第五章 the semantics of construction destruction and copy

5.1 无继承的对象构造

  1. bitwise member copy
  1. ADT class 执行default copy constructor,copy constructor, destructor,但是并不产生相应函数
  • 构造函数初始化vptr,构造函数不可以虚,构造函数内部调用虚拟函数不能实现多态只能调用本地版本
  • 传值方式传回一个local class object 时最好定义一个copy constructor,以避免被NRV优化

5.2 继承体系下的对象构造

  • vptr 初始化语义学

    • 在class的constructor 或者 destructor 中调用一个virtual function ,调用的必须是本class 中的那个function实体
    • vptr初始化时间在base class constructor 调用后member initialization list 所列members之前,以保证初始化过程中幻化出完整的基类对象

  • 只有在默认行为不安全或者不正确是才需要设计一个copy assignment operator

  1. dervied class constructor 中所有virtual base class 和base class constructor 被调用
  2. 对象vprt被设置,指向相关virtual function table
  3. member initialization list 在constructor 内部展开
  4. 执行程序直接赋值代码和生成对象的代码
  • 不要在虚基类中声明数据,避免copy assignment operator 的不完整性

5.5 semantics of destructor

  • 如果class 未声明destructor 且member object 拥有destructor ,编译器自动合成destructor,否则不合成
  1. destructor 函数本身最先执行
  1. 拥有destructor 的 member class object按声明顺序相反执行自己的destructor
  2. object 内带vptr 重置,指向响应基类virtual table
  3. 直接上层的nonvirtual base class 以其声明的顺序的逆序执行destructor
  4. virtual base class 按照与构造顺序相反的顺序执行destructor

第六章 runtime semantics

6.2 new delete 运算符

- new 和delete 底层以malloc 和free 实现
- new 失败,必须在new 内部完成已分配空间的释放

6.3 临时对象的处理

- 临时对象的销毁,必须在完整表达式求值过程的最后,该完整表达式造成临时对象的生成
- 如果临时对象被reference 对象将残留到reference 生命周期结束

第七章 on the cusp of the object model

template

> member function 只在使用时具现出来
- template class 中所有与类型有关的检验,如果牵涉到template 参数,都将延迟到真正的具现操作发生

异常处理

- exception handing 快速检阅
> 0. throw 子句,发出exception
1. 多个catch 子句捕获相应类型的exception
2. try区段处理
- 异常抛出后,控制权转移,函数调用也被推离,在函数堆栈推离前local class objects 的destructor会被调用





直到找到一个吻合的catch子句,或者直到堆栈被unwound而terminate已被调用

- 异常对象以复制构造方式传入catch子句,处理完成后后local excepton object被销毁,处理终结或者将原异常对象继续抛出

RTTI

>  dynamic_cast 通过vptr指向type_info运行时判定类型实现转型,比static_cast代价高但是更安全
> dynamic_cast 应用于pointer 时,安全转型则直接向下转型,不安全则pointer置0
> dynamic_cast 应用于reference 时,安全转型则直接向下转型,不安全则返回一个bad_cast exception
> typeid 返回一个 const reference,类型为type_info,

深入探索c++对象模型的更多相关文章

  1. 读书笔记《深度探索c++对象模型》 概述

    <深度探索c++对象模型>这本书是我工作一段时间后想更深入了解C++的底层实现知识,如内存布局.模型.内存大小.继承.虚函数表等而阅读的:此外在很多面试或者工作中,对底层的知识的足够了解也 ...

  2. 柔性数组-读《深度探索C++对象模型》有感 (转载)

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  3. 柔性数组-读《深度探索C++对象模型》有感

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  4. [读书系列] 深度探索C++对象模型 初读

    2012年底-2014年初这段时间主要用C++做手游开发,时隔3年,重新拿起<深度探索C++对象模型>这本书,感觉生疏了很多,如果按前阵子的生疏度来说,现在不借助Visual Studio ...

  5. 拾遗与填坑《深度探索C++对象模型》3.3节

    <深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...

  6. 拾遗与填坑《深度探索C++对象模型》3.2节

    <深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...

  7. 深度探索C++对象模型

    深度探索C++对象模型 什么是C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各个支持的底层实现机制. 抽象性与实际性之间找出平衡点, 需要知识, 经验以及许多思考. 导读 这本书是C+ ...

  8. 《深度探索C++对象模型》读书笔记(一)

    前言 今年中下旬就要找工作了,我计划从现在就开始准备一些面试中会问到的基础知识,包括C++.操作系统.计算机网络.算法和数据结构等.C++就先从这本<深度探索C++对象模型>开始.不同于& ...

  9. C++的黑科技(深入探索C++对象模型)

    周二面了腾讯,之前只投了TST内推,貌似就是TST面试了 其中有一个问题,“如何产生一个不能被继承的类”,这道题我反反复复只想到,将父类的构造函数私有,让子类不能调用,最后归结出一个单例模式,但面试官 ...

  10. 深入探索C++对象模型(一)

    再读<深入探索C++对象模型>笔记. 关于对象 C++在加入封装后(只含有数据成员和普通成员函数)的布局成本增加了多少? 答案是并没有增加布局成本.就像C struct一样,memeber ...

随机推荐

  1. JAVA的单例模式与延时加载

    延迟加载(lazy load)是(也称为懒加载),也叫延迟实例化,延迟初始化等,主要表达的思想就是:把对象的创建延迟到使用的时候创建,而不是对象实例化的时候创建.延迟加载机制是为了避免一些无谓的性能开 ...

  2. lua判断表中数据是否连续,0可以代表任何数

    最近看到有lua面试题,挺有意思的,一张表中有若干个数,0可以代表任何数 比如有张表{9, 2, 4, 1, 3, 0, 0, 0, 0},按照规则这张表中的四个0可以用来代表5,6,7,8,那么这张 ...

  3. GC 源码分析

    java对象的内存分配入口 Hotspot 源码解析(9) •内存代管理器TenuredGeneration对垃圾对象的回收2015-01-18阅读1154 •内存代管理器DefNewGenerati ...

  4. UI崩溃的解决方案

    在unity加载的时候主动强制关闭后,竟然ui崩溃,一直报错UnityEngine.UI.dll is in timestamps but is not known in assetdatabase. ...

  5. mongoDB之Pipeline Aggregation Stages

    原文链接:https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/ 管道聚合 $project Reshapes ...

  6. android源码的目录结构

    android源码的目录结构 [以下网络摘抄] |-- Makefile ! l/ a5 n% S% @- `0 d# z# a$ P4 V3 o7 R|-- bionic              ...

  7. [2014.01.27]wfGifAnimator 动画GIF组件 3.0

    组件支持设置GIF帧延时和获取GIF的帧延迟. 组件支持添加或插入或更新帧(支持bmp/jpg/gif/wmf/emf/ico格式).删除帧.清空帧操作. 组件支持GIF动画缩放大小. 组件支持绘制线 ...

  8. 崽崽帮www.zaizaibang.com精选14

    [行走贵州]爽爽贵阳,乐活天堂! 北京儿童医院将建遗传代谢病专科医院 [山东十大最难懂方言]原来青岛话还是很好懂滴 ❤如果南宁的儿童医院长这样…… 成都三所小学入围中国百强小学名单 [乐湖新闻]学习中 ...

  9. IOS:Safari不兼容Javascript中的Date问题

    在IOS5以上版本(不包含IOS5)中的Safari浏览器能正确解释出Javascript中的 new Date('2013-10-21') 的日期对象. 但是在IOS5版本里面的Safari解释ne ...

  10. [zz] 基于国家标准的 EndNote 输出样式模板

    基于国家标准的 EndNote 输出样式模板 https://cnzhx.net/blog/endnote-output-style-cnzhx/ 发表于 2013-05-26 作者 Haoxian ...