第1章 关于对象
1、C++在布局以及存取时间上的主要的额外负担是由virtual引起的,包括:

a、virtual
function机制,引入vptr以及vtbl,支持一个有效率的"执行期绑定" 
b、virtual
base class,用以实现"多次出现在继承体系中的base class,有一个单一而被共享的实例" 
c、多重继承下,派生类跟第二个以及后续基类之间的转换

2、"指针的类型"会教导编译器如何解释某个特定地址中的内存内容以及其大小(void*指针只能够持有一个地址,而不能通过它操作所指向的object)
3、C++通过class的pointers和references来支持多态,付出的代价就是额外的间接性。它们之所以支持多态是因为它们并不引发内存中任何"与类型有关的内存委托操作(type-dependent
commitment)",会受到改变的,只有他们所指向的内存的"大小和内容的解释方式"而已。

 
 
第2章
构造函数语意学

 
 
第3章
Data语意学
1、类对象大小受三个因素影响

a、virtual
base和virtual function带来的vptr影响 
b、 EBO (Empty
Base class Optimize)空基类优化处理,EBC(Empty Base
Class)占用一个字节,其他含有数据成员的从EBC派生的派生类,只会算自己数据成员的大小,不受EBC一字节的影响 
c、alignment
字节对齐

2、Nonstatic
data members在class object中的排列顺序将和其被声明顺序一样,任何中间介入的static data
members都不会被放进布局之中。
3、静态成员变量
static data members

a、存放在程序的data
segment之中 
b、通过指针和对象来存取member,完全一样,不管继承或者是虚拟继承得来,全局也只存在唯一一个实例 
c、静态常量成员可以在类定义时直接初始化,而 普通静态常量成员只能在.o编译单元的全局范围内初始化

4、非静态成员变量
nonstatic data members

a、 每一个nonstatic
data member的偏移量在编译时即可获知 ,不管其有多么复杂的派生,都是一样的。通过对象存取一个nonstatic
data member,其效率和存取一个C struct member是一样的。 
b、从对象存取obj.x和指针存取pt->x有和差异? 
 
   当继承链中有虚基类时,查找虚基类的成员变量时延迟到了执行期,根据virtual class offset查找到虚基类的部分,效率稍低 
 
   (成员变量的数据存取并没有this指针的变化)

成员变量的具体分布详情参见C++内存分布

 

第4章
Function语意学

1、C++的设计准则之一:nostatic
member function 至少必须和一般的nonmember function有相同的效率。

a、改写函数原型,在参数中增加this指针 
b、对每一个"nonstatic
data member的存取操作"改为由this指针来存取
c、将member
function重写为一个外部函数,经过"mangling"处理(不许要处理的加上 extern "C")

2、覆盖(override)、重写(overload)、隐藏(hide)的区别

重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。

覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。
隐藏 是指派生类中的函数把基类中相同名字的函数屏蔽掉了。隐藏与另外两个概念表面上看来很像,很难区分,其实他们的关键区别就是在多态的实现上。

3、静态成员函数
static member functions

a、不能访问非静态成员 
b、不能声明为const、volatile或virtual 
c、参数没有this 
d、可以不用对象访问,直接  类名::静态成员函数  访问

4、C++多态(polymorphism)表示"以一个public
base class的指针(或者reference),寻址出一个derived class object"
5、vtable虚函数表一定是在编译期间获知的,其函数的个数、位置和地址是固定不变的,完全由编译器掌控,执行期间不允许任何修改。
6、vtable的内容:

a、virtual
class offset(有虚基类才有) 
b、topoffset 
c、typeinfo 
d、继承基类所声明的虚函数实例,或者是覆盖(override)基类的虚函数 
e、新的虚函数(或者是纯虚函数占位)

7、执行期虚函数调用步骤

a、通过vptr找到vtbl 
b、通过 thunk技术以及topoffset调整this指针 (因为成员函数里面可能调用了成员变量) 
c、通过 virtual
class offset找到虚基类共享部分的成员 
d、执行vtbl中对应slot的函数

8、多重继承中,一个派生类会有n-1个额外的vtbl(一个可能有n或者n以上个vtbl,看是否有虚基类),它与第一父类共享vtbl,会修改其他父类的vtbl
9、函数性能

Inline
Member > (Nonmember Friend, Static Member, Nonstatic Member) > Virtual
Member > Virtual Member(多重继承) > Virtual Member(虚拟继承)

10、Inline对编译器只是请求,并非命令。inline中的局部变量+有表达式参数-->大量临时变量-->程序规模暴涨

 
第5章
构造、析构、拷贝语意学
1、析构函数不能定义为纯虚函数,以为每个子类的析构函数都会被编译器扩展调用基类的析构函数以及再上层的基类的析构函数。因为只要缺乏任何一个基类的析构函数的定义,就会导致链接失败。
 
   (实际上纯虚函数是可以被定义以及静态调用-类名::函数,但是C++标准为纯虚函数就是代表没有定义)
2、继承体系下带有数据成员的构造顺序

a、虚基类构造函数,从左到右,从顶层到底层。它和非虚基类不同:是由最底层子类调用的。 
b、非虚基类构造函数,按照基类被声明的顺序从左到右调用。它与虚基类不同:是由直接之类调用的。 
c、如果类中有虚表指针,则设置vptr初值,若有新增虚函数或者是覆盖基类虚函数,修改vtbl内容(实际上vtble在编译时,类定义时就已经建立好了) 
d、成员变量以其声明顺序进行初始化构造 
e、构造函数中,用户自定义代码最后被执行

3、如果类没有定义析构函数,那么只有在类中含有成员对象或者是基类中含有析构函数的情况下,编译器才会自动合成一个出来
4、析构函数的顺序跟构造函数的顺序完全相反,如果是为了多态的析构函数,设置为虚析构函数
5、不要在构造函数和析构函数中调用虚函数

 
第6章
执行期语意学
1、尽量推迟变量定义,避免不必要的构造和析构(虽然C++编译器会尽量保证在调用变量的时候才进行构造,推迟变量定义会使得代码好阅读)
2、全局类变量在编译期间被放置于data段中并被置为0

GOOGLE
C++编程规范: 
禁止使用class类型的静态或全局变量,只允许使用POD型静态变量(Plain
Old Data)和原生数据类型。因为它们会导致很难发现的bug和不确定的构造和析构函数调用顺序 
解决: 
改成在static函数中,产生局部static对象

3、如果有表达式产生了临时对象,那么应该对完整表达式求值结束之后才摧毁这些创建的临时对象。有两个例外:1)该临时对象被refer为另外一个对象的引用;2)该对象作为另一对象的一部分被使用,而另一对象还没有被释放。

第7章
站在对象模型的尖端
1、对于RTTI的支持,在vtbl中增加一个type_info的slot
2、dynamic_cast比static_cast要花费更多的性能(检查RTTI释放匹配、指针offset等),但是安全性更好。
3、对引用施加dynamic_cast:1)成功;或2)抛出bad_cast异常;对指针施加:1)成功;2)返回0指针。
4、使用typeid()进行判断,合法之后再进行dynamic_cast,这样就能够避免对引用操作导致的bad_cast异常:
if(typeid(rt) == typeid(rt2))
…。但是如果rt和rt2本身就是合法兼容的话,就会损失了一次typeid的操作性能。

深入探索C++对象模型 读书笔记的更多相关文章

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

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

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

    前言中的内容: 1.什么是C++对象模型? 1.语言中直接支持面向对象程序设计的部分 2. 对于各种支持的底层实现机制 2. C++ class的完整virtual functions在编译时期就固定 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

    member的各种调用方式 C++支持三种类型的member functions:static.nonstatic和virtual. nonstatic member functions会被编译器转换 ...

随机推荐

  1. 剑指offer 面试32题

    面试32题: 题目:从上到下打印二叉树 题:不分行从上到下打印二叉树 解题代码: # -*- coding:utf-8 -*- # class TreeNode: # def __init__(sel ...

  2. iOS UIScrollView 滚动到当前展示的视图居中展示

    需求展示: 测试效果1 first uiscrollView  宽度 为屏幕宽度   滚动步长 为 scroll 宽度的1/3   分析: 这个是最普通版 无法使每一次滚动的结果子视图居中展示, WA ...

  3. “中兴捧月”比赛之——二叉查找树(BST)树的最短路径Java求解

    问题描述: BST树,又称二叉查找树,求其到所有叶子节点路径的最小值 测试用例一:  10 5 20 返回15: 测试用例二: 100 20 70 110 120 10 null null 89 nu ...

  4. 【Topcoder】SRM158 DIV2总结

    250分题:给定一个4位字符串initial和rotate这个字符串的方式,然后再给另一个字符串current,问current能否由initial通过rotate得到,需要几次rotate? 简单的 ...

  5. 【Head First Servlets and JSP】笔记8:监听者

    1.你不用了解所有监听者API,并不多,一共有8个.不过,你需要知道你能监听什么,以便在需要的时候可以查. 2.关于Session和Cookie.参见JavaWeb学习总结(十二)——Session ...

  6. this对象解析

    this在js中有着非常广泛的应用,但其所指的对象也常常让人摸不着头脑,简而言之: this指的就是调用函数的对象,最常见的莫过以下几种 1.直接使用函数,则为window对象 function a( ...

  7. NoSQL数据库memcache和redis区别

    在web后台发开面试中,经常会被问道memcache和redis的区别和使用情况. 其中memcache和redis都是基于内存存储的缓存系统,存储形式key--value键值对的形式. 区别: 1. ...

  8. get_class_methods--返回由类的方法名组成的数组

    get_class_methods--返回由类的方法名组成的数组 array get_class_methods ( mixed $class_name ) 返回由类的方法名组成的数组. <?p ...

  9. JDK的安装配置

    1.下载JDK安装包(http://www.oracle.com/technetwork/java/javase/downloads/index.html),现在Java已经更新到JDK 8了,但是很 ...

  10. jupyter && ipython notebook简介

    2017-08-19 最近用了一下 ipython notebook 也就是 jupyter,这里有一个介绍还不错: http://www.cnblogs.com/howiewang/p/jupyte ...