《Effective C++》读书摘要

转:http://www.cnblogs.com/fanzhidongyzby/archive/2012/11/18/2775603.html

最近刚读完侯捷的《Effective C++》,相对来说,这本书的内容比较贴近基础,对于刚掌握C++基础的人会有不少的提高。不过书中还是涉及了不少C++的高级特性,阅读起来需要查阅相关的资料。书中给出了大量的示例和代码来说明具体规则的原理,我按照书中给出的标题将每个条目的关键内容整理如下。一方面是保留一份读书笔记,另一方面也是为了方便日后查阅方便。当然,如果不能从简单摘要的内容回忆起具体信息,到时再查书也不迟。同时也期望大家能从中找到自己没有注意的知识点,有所提高,大牛勿喷~ ?。

(一)、让自己习惯C++

一、C++语言联邦

多重范型编程语言:过程式、面向对象式、函数式编程、泛型编程、模板元编程。

二、const、enum、inline替换#define

const:代替宏变量有助于编译器理解;

enum:enum hack,更像define,不消耗内存,无法取地址;

inline:宏函数尽量用inline代替。

三、const

const返回值:避免(a*b)=c的错误;

const参数:传递指向常量的引用;

const成员函数:允许const属性的重载。

四、对象使用前初始化

构造函数成员初始化列表;

使用时调用,单例模式,多线程不安全。

(二)、构造/析构/赋值运算

五、C++默认编写的函数

默认构造、复制构造、析构、赋值运算符

六、拒绝自动生成的函数

私有化拷贝构造和赋值运算符;

私有继承UnCopyable手工类。

七、多态基类声明虚析构函数

(不)具有多态性质基类(不)需要虚析构函数;

八、不让异常逃出析构

异常时终止或者吞下;

将可能抛出异常的代码提供给用户管理;

九、不在构造和析构中调用虚函数

调用后仅仅是自身的虚函数,而非子类;

需要子类构造信息解决方案:子类使用静态函数构造基类的参数。

十、operator=返回*this的引用

允许连续赋值。

十一、operator=处理自我赋值

注意资源的释放顺序。

十二、复制对象要面面俱到

不要丢失基类的成员的复制。

(三)、资源管理

十三、对象管理资源

构造函数获得资源,析构函数释放资源;

使用智能指针封装:tr1::shared_ptr和auto_ptr。

十四、资源管理中小心copying

互斥锁加解锁的对象禁止复制;

引用计数法,tr1::shared_ptr<Mutex> mutex_ptr(pm,unlock),含有删除器的指针。

十五、资源管理类提供原始资源访问

原始资源获取;

隐式转换——类型转换函数。

十六、new-delete同型成对

[]的出现与否要对应起来,即使使用了typedef重命名了数组类型。

十七、独立成句的new对象放入智能指针

将new对象转换为智能指针作为参数,可能会被编译器结合其他参数调整顺序,造成内存泄漏。、

(四)、设计与声明

十八、让接口易用而不误用

类型一致性;

shared_ptr防范跨DLL错误。

十九、设计class犹如设计type

12条准则。

二十、常引用参数代替值传递

前者高效,但是对于内置类型除外。

二十一、需要返回对象时候不要返回引用

栈、堆、静态对象都不要作为引用返回。

二十二、成员变量声明为private

两种访问权限:private和others;

protected并不比public封装性好。

二十三、用非成员函数和非友元函数替换成员函数

封装强度和改变强度成反比,因为只影响有限的用户;

类外访问函数封装性好于累内成员函数的封装性,不增加累内私有数据的访问函数的数量;

二十四、参数需要类型转换应使用非成员函数

针对二元运算符重载。

二十五、没有异常的swap函数

类外构造特化的swap函数;

不要在swap的时候产生异常。

(五)、实现

二十六、延后变量定义式

不要提前定义,直到使用改变量的前一刻为之;

针对循环内的对象需要根据构造析构与赋值的成本,以及可维护性进行权衡。

二十七、少做转型操作

Base(*this).virFun()只会影响对象的基类部分的数据副本,不会影响对象本身,如果使用指针类型转换则会无穷递归,去掉虚属性则消除类似问题;

用虚函数的特性代替dynamic_cast;

尽量使用C++风格的转型。

二十八、避免返回对象内部数据的引用或指针

破坏了封装型;

函数返回对象析构导致空指针。

二十九、异常安全的努力

对象管理资源;

copy-swap实现技术;

异常安全性取决于最弱安全保证的代码。

三十、inline里里外外

隐式:累内直接定义成(友)员函数,显式:inline关键字;

拒绝:复杂、虚函数、函数指针调用、模板、构造析构函数、影响动态连接或升级、对调试器的挑战(禁用)。

三十一、降低文件间编译依存关系

能使用引用和指针完成的不使用对象、用class声明代替定义,并提供不同的头文件——程序库文件和类定义头文件;

handle class和interface class解除了接口与实现的耦合关系。

(六)、继承与面向对象设计

三十二、确定public继承塑膜出is-a关系

适用于基类的事情也适用于子类。

三十三、避免遮掩继承来的名称

基类的重载函数一旦在子类被重写后,其他的同名函数无法访问。

三十四、区分接口继承和实现继承

接口声明为纯虚函数,实现单独列出;

纯虚函数指定接口继承,虚函数指定接口和默认实现,一般函数指定接口和强制实现。

三十五、考虑虚函数以外的选择

私有虚函数在父类被调用的时候自动多态,基本保留何时调用的权力,子类拥有修改功能的权力;

function函数指针对象使得函数指针更加灵活;

古典策略模式:

使得不同的功能通过继承HealthCalcFunc改变。

三十六、绝不定义继承的非虚函数

重修继承的非虚函数导致函数的访问由指向对象的指针或引用类型决定。

三十七、绝不定义继承的默认参数值

重载的虚函数的默认参数来自于基类;

将默认参数函数声明为普通成员函数,调用私有的虚函数即可。

三十八、用复合塑膜出has-a和实现关系

has-a:对象的包含关系;

实现:对象对另一个对象进行具体特化。

三十九、审慎使用private继承

私有继承表达的是实现关系,子类使用父类提供的接口,但是不继承;

能用复合不用私有继承;

如何实现final字段:

这样Widget的子类就不会修改onTick函数了,将内部类移出,换做声明可以降低耦合;

private继承的空基类的大小实际为0,一般对象大小不能为0;

需要基类protected成员或者重写虚函数时候可以考虑使用private继承。

四十、审慎使用多重继承

使用虚基类导致速度变慢;

多重继承中使用公有继承继承接口,私有继承完成实现关系。

(七)、模板与泛型编程

四十一、隐式接口与编译多态

class是显示接口——函数签名,运行多态——虚函数;

template是隐式接口——有效表达式,编译多态——模板具体化与函数重载解析。

四十二、typename双重含义

模板声明中与class没有任何区别;

嵌套从属类型的显式指定,不能出现在基类列表和初始化列表中;

四十三、处理模板化基类名称

继承模板化基类的名称不能像继承一样使用:通过this->名字修饰、using 基类<T>::名字、或者基类<T>::名字一共三种修饰方式。第三种导致虚函数功能失效。

四十四、参数无关代码抽离模板

将与模板无关的非类型参数转移到类内;

尽量降低与模板无关的类型参数的膨胀度。

四十五、运用成员函数模板接受兼容类型

成员函数使用函数模板兼容更多类型;

函数模板声明后的copy构造和编译器生成的并不同,需要单独处理。

四十六、类型转换时为模板定义非成员函数

对于模板化的类要支持双操作运算符重载,首先必须是非成员函数,另外为了能让模板具体化必须将函数定在类体内部,因此只能将之声明为友元类型。(并非模板类内的友元函数必须类内定义)。

四十七、使用traits 类表现类型信息

STL五大迭代器:

1.输入迭代器:向前,一次一步,只读一次,istream_iterator。

2.输出迭代器:向前,一次一步,只写一次, ostream_iterator。

3.前向迭代器:向前,一次一步,可读可写多次,单向列表。

4.双向迭代器:向前向后,一次一步,可读可写多次,list、set、map。

5.随机迭代器:向前向后,一次多步,可读可写多次,vector、deque、string。

实现迭代器累加操作时候需要根据迭代器类型执行不同的操作方式,这种判断属于编译时期的判断,不应该使用if语句!

可以根据iterator_traits提供的类别标签区分迭代器类型,类别标签是空结构体类型,将标签作为函数参数,可以保证编译器能在编译时期对类型进行检查。

现在就可以把doAdvance封装起来自动完成编译期类型判断。

四十八、模板元编程

让某些事情变得容易可能,将某些工作从运行期转移到编译期;

分支——借由模板特化实现;

循环——借由递归完成;

优点:保证度量单位的正确、优化矩阵运算生成客户定制设计模式实现品;

避免了生成某些特殊类型不适合的代码。

(八)、定制newdelete

四十九、new-handler行为

set_new_handler指定内存分配失败时调用的函数。

五十、new、delete合理替换时机

改善性能,内存对齐,heap错误调试,收集heap信息。

五十一、new、delete固守常规

new含有无限循环分配内存,无法分配调用new-handler,处理0字节和超额申请;

delete处理null指针和超额申请。

五十二、写了placement new就要写placement delete

placement new在已有的缓冲区内申请对象;

不要掩盖已有的版本。

(九)、杂项

五十三、不要忽视警告

严肃对待警告信息;

不过度依赖警告信息。

五十四、熟悉TR1标准库

智能指针、Boost库。

五十五、熟悉Boost

社群、网站;

TR1组件实现品。

时间: 2024-10-11 11:50:51

《Effective C++》读书摘要的相关文章

《地质灾害防治这一年2013》读书摘要

最近把这本部里每年都印的当年的总结材料看了一下,摘录一些内容: 要求:防灾部署科学有序.督促检查及时有效.部门协作紧密到位.应急处置迅急有力.防治能力建设取得了更加显著的成效,调查评价取得了显著进展.监测预警得到了有效落实.资金投入力度不断加大.应急体系更加完善. 2014年工作要求:1.深入贯彻落实<决定>,2.推进高标准十有县建设,3.落实汛期各项防灾措施,4.做好应急处置工作. 地质灾害防治工作关系到人民群众生命财产安全,也是维护社会公共安全,维护地质环境安全的基础性工作,是生态文明建设

地质灾害防治工作的经验和体会

最近写材料的时候,总结了一下地灾防治工作中一些经验和体会.如下: (一)领导重视是地质灾害防治工作的前提和保障. 国土资源部.省委和省政府对地质灾害防治工作的高度重视,为我省地质灾害防治工作指明了方向,是我省地质灾害防治工作的组织保障.特别是今年省政府将地质灾害防治工作纳入省政府“十件民生实事”,将地质灾害防治工作的重要程度提升到了新的高度,各地级以上市政府纷纷加大了地质灾害隐患点搬迁和治理经费投入,大大推进了全省的地质灾害防治工作. (二)群专结合是做好地质灾害防治工作的关键. 群测群防体系的

读书摘要

点击查看[读书摘要] 原文地址:https://www.cnblogs.com/allearner/p/11459730.html

读书摘要:第七章 闩Suan锁和自旋锁

摘要: 1.闩锁就像是内存上的锁,随着越来越多的线程参与进来,他们争相访问同一块内存,导致堵塞.2.自旋锁就是闩锁,不同之处是如果访问的内存不可用,它将继续检查轮询一段时间.3.拴锁和自旋锁是我们无法控制的,由sqlserver自动维护,但是我们应积极寻找避免他们发生堵塞的方法.4.id作为聚集索引时,当数据量增加时最后一个数据页将成为热点,征用就会发生.避免有经常行数据插入操作的表使用自增ID,改为guid.5.队列操作的数据表也应该避免ID的聚集索引问题.6.无论何时将数据插入到没有聚集索引

JAVA设计模式(DESIGN PATTERNS IN JAVA)读书摘要 第1部分接口型模式——第3章 适配器(Adapter)模式

客户端代码提供接口来写具体实现类时,要利用已经实现接口功能的现有类,但是接口的方法名和现有类的方法名不一致,则需要使用适配器模式. 接口适配 如图所示, RequiredInterface接口声明了Client类所要调用的requiredMethod()方法,ExistingClass的usefulMethod()提供了此方法的具体实现,但是这两个方法的名字不同,这要对ExistingClass进行适配.适配类NewClass继承ExistingClass类,实现了RequiredInterfa

&lt;Effective C++&gt;读书摘要--Resource Management&lt;一&gt;

1.除了内存资源以外,Other common resources include file descriptors, mutex locks, fonts and brushes in graphical user interfaces (GUIs), database connections, and network sockets. Regardless of the resource, it's important that it be released when you're fini

HeadFirst SQL 读书摘要

数据库都是用 圆柱形表示的. 数据库中包含表 表中包含行和列 行又叫记录record,  列又叫 字段field 创建数据库 create database mypipe_l; 选择数据库 use mypipe_l; 创建表 create table doughnut( name VARCHAR(10), type VARCHAR(6) ); 查看表 desc doughnut; 删除表 drop table doughnut; 插入数据 insert into doughnut (name,

&lt;Effective C++&gt;读书摘要--Designs and Declarations&lt;三&gt;

<Item 22> Declare data members private 1.使数据成员private,保持了语法的一致性,client不会为访问一个数据成员是否需要使用括号进行函数调度,还是不使用括号直接访问成员而纠结. 2.使数据成员private,if you use functions to get or set its value, you can implement no access, read-only access, and read-write access. Heck

Java设计模式(Design Patterns In Java)读书摘要——第1章 绪论

为何需要模式 模式是做事的方法,是实现目标,研磨技术的方法.通俗点说,模式是为了解决某个行业的某个问题的有效的方法或技艺. 为何需要设计模式 为了提升代码的水准,是代码变得简洁而易用.模式是一种思想,而不是具体的实现. 为何选择Java 集大成,流行,发展前景好 UML 一种统一建模语言 挑战 多思考,多练习 本书的组织 1.接口型模式 2.职责型模式 3.构造型模式 4.操作型模式 5.扩张型模式 模式的分类具有主观色彩,你也可以根据自己的见解提出不同的分类. 欢迎来到Oozinoz 本书的挑