读书笔记之:Effective C++ (2005)[++]

条款01:视C++为一个语言联邦

条款02:尽量以const,enum,inline替换#define

条款03:尽可能使用const

条款04:确定对象使用前先被初始化

条款05:了解C++默认编写并调用哪些函数

条款06:若不想使用编译器自动生成的函数,就该明确拒绝

条款07:为多态基类声明virtual析构函数

条款08:别让异常逃离析构函数

1. 编译单元

为免除"跨编译单元之初始化次序"问题,请以local static 对象替换non-local static对象。为免除"跨编译单元之初始化次序"问题,请以local static 对象替换non-local static对象。

2. 了解C++默认编写并调用哪些函数

默认构造函数,拷贝构造函数,赋值操作符和析构函数。如果写一个空类,编译器会自动生成上面4个函数。注意:只有当这些函数被需要(被调用)的时候,编译器才会创建它们。

如果你打算在一个内含reference成员的class内支持赋值操作,你必须自己定义copy assignment操作符。面对"内含const成员"的classes,编译器的反映也一样。

条款9:绝不再构造和析构函数过程中调用virtual函数

条款10:令operator=返回一个reference to *this

条款11:在operator=中处理"自我赋值"

条款12:复制对象时勿忘每一个成分

copying函数应该确保复制"对象内的所有成员变量"及"所有base class成分"

不要尝试以某个copying函数实现另一个copying函数。应该将共同部分放进第三个函数中,并由两个copying函数共同调用。

条款13:以对象管理资源

获得资源后立即放进管理对象。以对象管理资源就是所谓的资源获得即初始化RAII。

管理对象运用析构函数确保资源释放。

引用计数型智能指针RCSP:持续追踪共有多少个对象指向某笔资源,并且在无人指向它时自动删除该资源。

两个经常使用的RAII 类分别是auto_ptr和tr1::shared_ptr。

条款14:在资源管理中小心copying行为。

当一个RAII对戏那个被复制时,会发生什么事?

复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。

普通而常见的RAII类copying行为是:抑制copying,施行引用计数法。不过其他行为也都可能被实现。

条款15:在资源管理类中提供对元素资源的访问。

将RAII类对象转换为其所含之元素资源的两个方法:显示转换和隐式转换。

tr1::shared_ptr和auto_ptr都提供了一个get成员函数,用于执行显示转换,返回智能指针内部的原始指针。同时,它们也重载了指针取值操作符(operator->和operator*),它们允许隐式转换成原始指针。

条款16:成对使用new和delete时要采取相同的形式。

new操作:内存分配,调用构造函数。delete操作:调用析构函数,内存释放。

单一对象布局一般不同于数组的内存布局。

条款17:以独立语句将newed对象置入智能指针

以独立语句将newed对象存储于智能指针内,如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。

条款18:让接口容易被正确使用,不易被误用。

条款19:设计class犹如设计type

条款20:宁以pass-by-reference-to-const替换pass-by-value

条款21:必须返回对象时,别妄想返回其reference

条款22:将成员变量声明为private

条款23:宁以non-member、non-friend替换member函数

条款24:若所有参数皆需类型转换,请为此采用non-member函数

条款25:考虑写出一个不抛出异常的swap函数

条款26:尽可能咽喉变量定义式的出现时间

条款27:尽量少做转型动作

条款28:比慢返回handles指向对象内部成分

条款29:为异常安全而努力是值得的

条款30:透彻了解inlining的里里外外

条款31:将文件间的编译依存关系降至最低

条款32:确定你的public继承塑膜出is-a关系

条款33:避免遮掩继承而来的名称

条款34:区分接口继承和实现继承

接口继承和实现继承不同。在public继承之下,derived classes总是继承base calss接口。

pure virtual 函数只具体指定接口继承。

简朴的(非纯)impure virtual函数具体指定接口继承及缺省实现继承。

non-virtual函数具体指定接口继承以及强制性实现继承。

条款35:考虑virtual函数以外的其他选择

条款36:绝不重新定义继承而来的non-virtual函数

条款37:绝不重新定义继承而来的缺省参数值:因为缺省参数值都是静态绑定,而virtual函数却是动态绑定的。

条款38:通过复合塑膜出has-a或根据某物实现出

条款39:明智而审慎的使用private继承

private继承:如果类之间的继承关系是private,编译器不会自动将一个派生类对象转换为一个基类对象。这和public继承的情况是不同的。还有是,从private基类继承而来的所有成员在派生类中都会变成private属性。


条款40:明智而审慎的使用多重继承

多重继承比单一继承复杂。它可能导致新的歧义性以及对virtual继承的需要。

virtual继承会增加大小、速度、初始化(及赋值)复杂度等成本。如果虚基类不带有任何数据,将是最具有使用价值的情况。

多重继承确实有正当用途。其中一个情节涉及"public继承某个Interface class"和"private继承某个协助实现的class"的两相组合。

条款41:了解隐式接口和编译期多态

面向对象编程世界总是以显式接口(explicit interface)和运行时多态(runtime polymorphism)解决问题。模板及泛型编程的世界与面向对象有根本不同,强调的是隐式接口(implicit interfaces)和编译时多态(complie-time polymorphism)。

类和模板都支持接口和多态。

对类而言,接口是显式,以函数签名为中心。多态则是通过虚函数发生在运行时。对模板参数而言,接口是隐式的,基于有效表达式。多态则是通过模板的实例化和函数重载解析发生在编译时。

条款42:了解typename的双重含义。

条款43:学习处理模板化基类内的名称

条款44:将与参数无关的代码抽离templates

条款45:运用成员函数模板接受所有兼容类型

条款46:需要类型转换时请为模板定义非成员函数

条款47:请使用traits classes表现类型信息

Traits并不是C++关键字或一个预先定义好的构件;它们是一种技术,也是一个C++程序员共同遵守的协议。这个协议的要求之一就是,它对内置类型和用户定义类型的表现一样好。

类型的traits信息必须位于类型自身之外。标准技术把它放进一个template及其一个或多个特化版本中。这样的templates在标准程序库中有若干个,其中针对迭代器的是

iterator_traits:
template <class IterT>
struct iterator_traits;

条款48:认识template元编程

条款49:了解new-handler的行为

条款50:了解new和delete的合理替换时机

条款51:编写new和delete时需固守常规

条款52:写了placement new也要写placement delete

条款53:不要轻易忽略编译器的警告

条款54:熟悉包括TR1在内的标准程序库

条款55:让自己熟悉Boost

 

 

 

 

 

 

posted @ 2012-08-19 21:47  Mr.Rico  阅读(255)  评论(0编辑  收藏  举报