effective C++里面说C++包含了C,Object-Oriented C++,Template C++和stl四种。
然而,根据最新标准,应该是以下五种:
constexpr
)引用参考
然而,正如条款1所说,应该将其视作语言联邦,在必要的时候,选择合适的编程范式进行编程
#define指定的常量不会进入符号表,在编译错误时不会弹出宏的名字。
其次,无法跨作用域地指定常量,如指定类专属常量时,作用域外#define依然奏效
最后,由于#define展开是应用序展开,与常规的函数展开(正则序)不同,应该使用inline替代
e.g #define multiply(a,b) a * b; multiply(3+4, 5+ 3)的结果是3 + 4 * 5 + 3,即26
03条款:尽可能使用const
需要改变的对象不加const,其他使用const避免了错误
04条款:确定对象使用前被初始化
有一点建议:声明变量可以在前面。初始化或者定义尽量延后,在使用前不久进行
05条款:了解C++默默编写了哪些函数
C++03:default构造函数,析构函数,copy构造函数,copy assignment运算符
C++11:除了以上还有move operation
06条款:明确拒绝编译器自动生成的函数
C++03:写空定义函数
C++11:=delete对函数
07条款:为多态基类声明virtual析构函数
指针多态的对象在析构时,能够根据实际对象进行析构,选择合适的析构函数
08条款:别让异常逃离析构函数
C++析构函数中,抛异常可能导致内存泄漏,并没有完全地释放内存,应当将抛异常的代码部分移到析构函数外,并且在析构前调用它们
同理,在构造函数中也不能抛异常,因为类未完成构建,也就不知道如何析构,会出现错误,同样应当把抛异常的代码部分移到构造函数外调用
09条款:不在构造和析构过程中调用virtual函数
未必会调用derived class中的函数,此时类不变式已经被打破。
10条款:令operator = 返回一个reference to *this
C++的=运算符就是这么规定的。所有重载必须和C++运算符中的规则匹配。
11条款:operator= 处理自我赋值
12条款:复制对象时勿忘每一个成分
13条款:对象管理资源
RAII,小心使用原始指针的pimpl模式的析构。
14条款:在资源管理类中小心copying行为
资源未必是可以复制的,不能复制的只能使用浅复制,最好还是使用引用计数的智能指针。
此外,还能够复制底部资源或者转移底部资源的拥有权(即C++11中的move语义)
15条款:在资源管理类中提供对原始资源的访问
有时APIs会要求对原始资源的范围呢
16条款:成对使用new和delete要采用相同形式
new[],delete[]配合;
new,delete配合;
placement new, placement delete配合;
17条款:以独立语句将newed对象置入智能指针
即智能指针管理资源
18条款:让接口易被使用,不易误用
良好的命名,何时的参数等等
19条款:设计class犹如设计type
20条款:以pass by reference to const替换pass by value
使用const by const提高了参数传递效率
21条款:必须返回对象时,别妄想返回reference
如果内部创建的对象,返回的reference在函数外内存已经释放了
可以返回对象副本,或者使用一个引用的对象作为函数的调用对象来作为返回值
22条款:成员变量声明为private
类的封装
23条款:宁以non-member,non-friend替换member函数
24条款:所有参数需要转换,使用non-member函数
扩展性更好,e.g类型转换的时候
25条款:考虑不抛异常的swap
26条款:尽量延后变量定义式的时间
27条款:少做转型
28条款:避免返回handles对象内部
暴露了对象内部,与封装思想相抵
29条款:为“异常安全”努力是值得的
不泄露任何资源,不允许数据败坏,
30条款:了解inlining的里里外外
插入到代码中,会使代码膨胀,应该只使用于小型函数
31条款:文件编译依存关系降至最低
尽量前置声明
32条款:public继承塑造is-a关系
33条款:避免遮掩的名称
遮掩即非virtual的父类和子类都有的同名函数,子类遮掩了父类的这个函数。
34条款:区分接口继承和实现继承
=0的使用,永远不会被实例化的类
35条款:考虑virtual函数以外的选择
template method模式,使用函数指针的strategy模式(其实现在可以使用bind,function对象来代替函数指针)
36条款:不重定义继承的non-virtual函数
也就是避免遮掩
37条款:不重定义继承而来的缺省参数
避免对父类和子类不同调用时产生不同的结果
38条款:通过复合构造出has-a
39条款:谨慎使用private继承
40条款:谨慎使用多重继承
41条款:了解隐式接口和编译器多态
模板的隐式接口即模板参数的限制(e.g能调用的子函数等等)
42条款:了解typename的双重定义
typename在模板参数中声明模板参数,也可以在模板定义内表明后面是一种类型
43条款:处理模板化基类的名称
对于模板参数是派生类,并且在此函数中调用了父类方法时,会被编译器报错,因为在编译期时不能访问该父类方法
应该在前面使用this->即指针多态或者using父类方法的作用域
44条款:参数无关的代码抽离template
45条款:成员函数模板接受所有兼容类型
46条款:类型转换为模板定义非成员函数
47条款:traits class表现类型信息
48条例:认识template模板元编程
49条款:定制new和delete
operator new无法分配内存时,调用客户的错误处理函数(new-handler),再抛出异常
50条款:new和delete的替换时机
1.检测错误(如dump)2.强化效能(自己定制内存分配器)3.收集统计数据
51条款:编写new和delete需要固守常规
52条款:写了placement new,也要写placement delete
53条款:不要轻视编译器警告
54条款:熟悉TR1
现在应该是boost,TR2了吧
cppreference