《深度探索C++对象模型》读书笔记(一)
前言
今年中下旬就要找工作了,我计划从现在就开始准备一些面试中会问到的基础知识,包括C++、操作系统、计算机网络、算法和数据结构等。C++就先从这本《深度探索C++对象模型》开始。不同于《Effective C++》,这本书主要着眼于C++实现的底层机制,因此我在写这个系列时默认读者已经熟悉C++的基本语法(包括类、继承、多态、泛型等等),将更多地介绍C++具体是如何实现这些语法的。这次我就先写第一、二章,之后每读两章都会更新该系列。如果你有什么问题,欢迎在博客的评论版块和我探讨,或者联系我的邮箱:kevinstigma@gmail.com,很乐意与你互相切磋、提高。
第一章:关于对象
在传统的C程序中,采用的是过程式的思维:“数据”和“处理数据的操作(函数)”是分开来声明的,它们二者之间并没有关联性。但到了C++里,倾向于采用独立的“抽象数据类型”(ADT)来实现数据的封装。从代码结构上来看,C++似乎比C要消耗更高的时间和空间成本,但事实未必如此。相比于C,C++在布局和时间上主要的额外负担是由virtual引起的,这分为两部分:
1.virtual function机制 用以支持一个有效率的“执行期绑定”。
2.virtual base class 用以实现“多次出现在继承体系中的base class,有一个单一而被共享的实例”。
接下来,书里介绍了三种的C++对象模式:简单对象模型、表格驱动对象模型、C++对象模型,其中第三种最为编译器所常用,因此在这里主要介绍第三种。
C++对象模型中,非nonstatic data members被配置于每一个class object之内,static data members、function members则被存放在class object之外。编译器为每一个class产生一个表格,表格里是一堆指向virtual functions的指针,该表格我们称之为virtual table(vtbl);每一个class object被安插一个指针,指向相关的virtual table,这个指针被称为vptr。vptr的设定和重置由constructor、destructor以及copy assignment运算符自动完成。每一个class所关联的type_info object也存放在virtual table之中。
该模型的优点是,它的空间和时间的效率较高;缺点在于,如果应用程序本身的代码未改变,而所用到的class object的nonstatic data members有所修改,那么应用程序的代码同样需要重新编译(因为内存分布发生了改变)。
在接下来的篇幅里,书中探讨了struct和class的区别,对于这个问题可以参考这篇博文:http://blog.csdn.net/omegayy/article/details/7470316。其实struct和class从语法本质上差别并不大,无非是二者的默认继承和默认成员访问级别不同。但从一般来说,我们习惯用struct来代表一些简单数据的集合,用class来代表更为复杂的封装、继承的数据。
与C不同,在C++中,对象的内存分布未必和类中成员的声明顺序一致,比如C++的编译器可能会将protected data members放在private data members前面存储,与声明顺序无关;同理,base classes和derived classes的data members的布局也未有谁先谁后的强制规定。但类中处于同一个access section中的数据,其内存分布顺序是按照声明顺序排列的,只是不同access section之间未必按声明顺序排列。
之后书中花了一些篇幅介绍多态的机制,我觉得熟悉C++的人应当对此并不难理解,在这里不再赘述。
第二章:构造函数语义学
本章主要介绍了C++中构造函数的生成机制。
首先是default constructor,C++的编译器真的会为每一个没有声明构造函数的类生成default constructor吗?其实并不是的。书中指出,只有四种情况,会造成“编译器必须为未声明constructor的classes合成一个default constructor”:
1.member constructor有defualt constructor;
2.base class具有default constructor;
3.该类具有virtual funciton;
4.该类具有一个virtual base class。
在合成的defualt constructor中,只有base class subobjcets和member class objects会被初始化,而所有其他的nonstatic data member(int、int*、char等类型)都不会被初始化。
之后是copy constructor。与defualt constructor一样,编译器并不是为所有无用户定义copy constructor的类都创建copy constructor,如上的四种情况下,编译器才会为class合成copy constructor;否则编译器会执行bitwise copy。
接下来书中介绍了NRV优化以及member initialization list。
对于NRV(Named Return Value)优化,我们可以看一个例子:
假设有一个foo函数:
X foo()
{
X xx;
if(...)
return xx;
else
return xx;
}
经过编译器的优化后,代码改成如下样子:
void foo(X &result)
{
result.X::X();
if(...)
{
return;
}
else
{
return;
}
}
这样就省去了临时对象的默认构造函数、拷贝构造函数、析构函数的成本,从而有助于减少运行时间。另外,有一点要注意的是,NRV优化,有可能带来程序员并不想要的结果,比如当你的类依赖于构造函数或者拷贝构造函数的调用次数时。
关于member initialization list,我们首先需要知道需要它的时机:
1.当初始化一个reference member时;
2.当初始化一个const member时;
3.当调用一个base class的constructor,而它拥有一组参数时;
4.当调用一个member class的constructor,而它拥有一组参数时。
接下来需要注意的一点就是:list中的初始化顺序是由class中member的声明顺序决定的,而不是由initialization list中的排列顺序决定的!这是一个非常容易出错的地方。
《深度探索C++对象模型》读书笔记(一)的更多相关文章
- 《html5 从入门到精通》读书笔记(一)
今天看了<html5 从入门到精通>这本书,感觉阅读下来很舒心,不像阅读其他书籍很揪心.html增加的知识点,我觉得非常有价值,看完几章记录了一些内容,不但能巩固,也为下次遗忘知识点做好准 ...
- HTML5从入门到精通(明日科技) 中文pdf扫描版
HTML5从入门到精通(明日科技) 中文pdf扫描版
- HTML5从入门到精通(千锋教育)免费电子版+PDF下载
本书是HTML5初学者极好的入门教材之一,内容通俗易懂.由浅入深.循序渐进.本书内容覆盖全面.讲解详细,其中包括标签语义化.标签使用规范.选择器类型.盒模型.标签分类.样式重置.CSS优化.Photo ...
- Unity Shader入门精要读书笔记(一)序章
本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...
- Oracle从入门到精通----学习笔记
书名:<Oracle从入门到精通:视频实战版>秦靖.刘存勇等编著 第4章 SQL基础 1.SQL语言分类 数据定义语言 --- DDL,Data Definition Language 数 ...
- MySQL数据库应用 从入门到精通 学习笔记
以下内容是学习<MySQL数据库应用 从入门到精通>过程中总结的一些内容提要,供以后自己复现使用. 一:数据库查看所有数据库: SHOW DATABASES创建数据库: CREATE DA ...
- Unity Shader入门精要读书笔记(二)UnityShader概述
第三章<UnityShader概述>的读书笔记: 1.Unity Shader模板提供了几种选择: 标准光照模型(新添加的基于物理的渲染方法) 不含光照的基本的顶点.片元着色器 屏幕后处理 ...
- 《html5 从入门到精通》读书笔记(二)
接着上面继续记录笔记,这次要记的知识点比较多...记录下我认为比较重要的东西. 一.表单属性 1.autocomplete属性 该属性规定form或input域应该拥有自动完成功能. <form ...
- 《html5 从入门到精通》读书笔记(三)
二.标签详解 标签 描述 4 5 <form> 定义表单. 4 5 <h1> to <h6> 定义标题1到标题6. 4 5 <head> 定义关于文档的 ...
- 《HTML5 CANVAS基础教程》读书笔记
一.HTML5简介 1.HTML5新特性 1)结构元素:section,header,hgroup,footer,nav,article,aside, 2)内容元素:figure,figcaption ...
随机推荐
- Linux中访问Apache报403错误处理方法
1.先说本地环境,脱离基础环境的解决策略都是耍流氓 (1)Linux:CentOS7.5 (2)Apache: Apache/2.4.6 (CentOS) (3)Apache的安装路径在 /usr/l ...
- jQuery-4.动画篇---动画切换的比较(toggle与slideToggle以及fadeToggle的比较)
jQuery中toggle与slideToggle以及fadeToggle的比较 操作元素的显示和隐藏可以有几种方法.例如: 改变样式display为none 设置位置高度为0 设置透明度为0 都能达 ...
- 2018 CCPC 网络赛 Buy and Resell
The Power Cube is used as a stash of Exotic Power. There are n cities numbered 1,2,…,n where allowed ...
- celery使用rabbitmq报错[Errno 104] Connection reset by peer.
写好celery任务文件,使用celery -A app worker --loglevel=info启动时,报告如下错误: [2019-01-29 01:19:26,680: ERROR/MainP ...
- python开发流程及项目目录规范
# 项目开发流程 1.调研 2.需求分析 ---产品经理 3.任务分配 ---项目经理 4.写项目demo ---项目经理.架构师.程序猿 5.架构分析 ---项目经理.架构师 6.编 ...
- C++实验七
#include <iostream> using namespace ::std; int main() { ios_base::fmtflags original_flags = co ...
- GitHub 优秀的项目地址
Type LibDescription LibLocation Android SlidingMenu https://github.com/jfeinstein10/SlidingMenu ...
- 【转载】 spring事物配置,声明式事务管理和基于@Transactional注解的使用
https://blog.csdn.net/bao19901210/article/details/41724355
- 基于C++的牛顿切线法演示
牛顿切线法 中心思想: 利用目标函数二阶泰勒多项式的最优解作为函数的近似最优解.如果新的近似最优解满足计算精度,则终止计算,否则将函数在新点展开成二阶泰勒多项式,用新的泰勒多项式的最优解作为函数的近似 ...
- 爬虫模块介绍--request(发送请求模块)
爬虫:可见即可爬 # 每个网站都有爬虫协议 基础爬虫需要使用到的三个模块 requests 模块 # 模拟发请求的模块 PS:python原来有两个模块urllib和urllib的升级urlli ...