天天看点

重读Effective C++

好久没看C++的书了,用C++需要注意非常多的陷阱,写起程序来确确实实是戴着镣铐跳舞。可是,没办法,找工作还是得靠它。前几天重读了Effective C++,还是很喜欢侯捷的语言,在这里把常用的注意事项记录下来。

1. 使用相同形式的new和delete

2. 总是让base class拥有virtual destructor(delete pBase调用哪个析构函数?)

3. 如果class内动态分配内存,请为此class声明一个copy constructor和一个assignment运算符(内存分配问题)

4. initialization list中的members初始化次序应该和其在class内的声明次序相同(class members按照声明顺序来初始化)

5. 令operation=传回"*this 的 reference"

6. 在operation=中为所有的data members设定内容(主要是base class部分,拷贝构造函数也要注意这个问题)

7. 在operation=中检查是否“自己赋值给自己”(动态内存问题)

8. 尽可能使用const

9. 尽量使用pass-by-reference 少用 pass-by-value(减少构造函数和析构函数的调用)

10. 当你必须传回object时,不要尝试传回reference( 空悬指针)

11. 明智地运用inlining(复杂函数、虚拟函数、构造函数、析构函数、对内联函数取地址都会使内联失败,对老的编译器会产生冗余副本)

12. 通过public inheritance模塑出“isa”关系;通过layering技术模塑出has-a或is implemented in terms of关系;通过private 继承实现is implemented in terms of关系,并可以调用父类的protected函数。优先使用layering技术。

13. 对于public继承,纯虚函数意味着接口继承;虚函数意味着接口和默认实现继承;非虚拟函数意味着接口和实现都被继承,“不变形凌驾于变异性之上”

14. 绝对不要重新定义继承而来的非虚拟函数(非虚拟函数是静态绑定)

15. 绝对不要重新定义继承而来的虚拟函数的缺省函数值(缺省函数值为静态绑定)

16. 避免在继承体系中做向下转型动作(重新设计类的层次)

17. 清楚知道C++编译器默默为我们完成和调用哪些函数(默认构造、拷贝构造、析构、赋值操作符、取地址)

18. 使用non-local static object之前确定它已有初值(初始化次序无保证,用singleton模式解决 )