增加 Effective C++

This commit is contained in:
huihut 2018-12-21 22:21:17 +08:00
parent f9be322744
commit 5360910365

View File

@ -1208,12 +1208,24 @@ class doSomething(Flyable *obj) // 做些事情
29. 为 “异常安全” 而努力是值得的异常安全函数Exception-safe functions即使发生异常也不会泄露资源或允许任何数据结构败坏分为三种可能的保证基本型、强列型、不抛异常型
30. 透彻了解 inlining 的里里外外inlining 在大多数 C++ 程序中是编译期的行为inline 函数是否真正 inline取决于编译器大部分编译器拒绝太过复杂如带有循环或递归的函数 inlining而所有对 virtual 函数的调用(除非是最平淡无奇的)也都会使 inlining 落空inline 造成的代码膨胀可能带来效率损失inline 函数无法随着程序库的升级而升级)
31. 将文件间的编译依存关系降至最低(如果使用 object references 或 object pointers 可以完成任务,就不要使用 objects如果能过够尽量以 class 声明式替换 class 定义式;为声明式和定义式提供不同的头文件)
32. 确定你的 public 继承塑模出 is-a 关系(适用于 base classes 身上的每一件事情一定适用于 derived classes 身上,因为每一个 derived class 对象也都是一个 base class 对象)
32. 确定你的 public 继承塑模出 is-a(是一种)关系(适用于 base classes 身上的每一件事情一定适用于 derived classes 身上,因为每一个 derived class 对象也都是一个 base class 对象)
33. 避免遮掩继承而来的名字(可使用 using 声明式或转交函数forwarding functions来让被遮掩的名字再见天日
34. 区分接口继承和实现继承(在 public 继承之下derived classes 总是继承 base class 的接口pure virtual 函数只具体指定接口继承;非纯 impure virtual 函数具体指定接口继承及缺省实现继承non-virtual 函数具体指定接口继承以及强制性实现继承)
35. 考虑 virtual 函数以外的其他选择(如 Template Method 设计模式的 non-virtual interfaceNVI手法将 virtual 函数替换为 “函数指针成员变量”,以 `tr1::function` 成员变量替换 virtual 函数,将继承体系内的 virtual 函数替换为另一个继承体系内的 virtual 函数)
36. 绝不重新定义继承而来的 non-virtual 函数
37. 绝不重新定义继承而来的缺省参数值因为缺省参数值是静态绑定statically bound而 virtual 函数却是动态绑定dynamically bound
38. 通过复合塑模 has-a有一个或 “根据某物实现出”在应用域application domain复合意味 has-a有一个在实现域implementation domain复合意味着 is-implemented-in-terms-of根据某物实现出
39. 明智而审慎地使用 private 继承private 继承意味着 is-implemented-in-terms-of根据某物实现出尽可能使用复合当 derived class 需要访问 protected base class 的成员,或需要重新定义继承而来的时候 virtual 函数,或需要 empty base 最优化时,才使用 private 继承)
40. 明智而审慎地使用多重继承(多继承比单一继承复杂,可能导致新的歧义性,以及对 virtual 继承的需要,但确有正当用途,如 “public 继承某个 interface class” 和 “private 继承某个协助实现的 class”virtual 继承可解决多继承下菱形继承的二义性问题,但会增加大小、速度、初始化及赋值的复杂度等等成本)
41. 了解隐式接口和编译期多态class 和 templates 都支持接口interfaces和多态polymorphismclass 的接口是以签名为中心的显式的explicit多态则是通过 virtual 函数发生于运行期template 的接口是奠基于有效表达式的隐式的implicit多态则是通过 template 具现化和函数重载解析function overloading resolution发生于编译期
42. 了解 typename 的双重意义(声明 template 类型参数是,前缀关键字 class 和 typename 的意义完全相同;请使用关键字 typename 标识嵌套从属类型名称但不得在基类列base class lists或成员初值列member initialization list内以它作为 basee class 修饰符)
43. 学习处理模板化基类内的名称(可在 derived class templates 内通过 `this->` 指涉 base class templates 内的成员名称,或藉由一个明白写出的 “base class 资格修饰符” 完成)
44. 将与参数无关的代码抽离 templates因类型模板参数non-type template parameters而造成代码膨胀往往可以通过函数参数或 class 成员变量替换 template 参数来消除因类型参数type parameters而造成的代码膨胀往往可以通过让带有完全相同二进制表述binary representations的实现类型instantiation types共享实现码
45. 运用成员函数模板接受所有兼容类型请使用成员函数模板member function templates生成 “可接受所有兼容类型” 的函数;声明 member templates 用于 “泛化 copy 构造” 或 “泛化 assignment 操作” 时还需要声明正常的 copy 构造函数和 copy assignment 操作符)
46. 需要类型转换时请为模板定义非成员函数(当我们编写一个 class template而它所提供之 “与此 template 相关的” 函数支持 “所有参数之隐式类型转换” 时,请将那些函数定义为 “class template 内部的 friend 函数”)
47. 请使用 traits classes 表现类型信息traits classes 通过 templates 和 “templates 特化” 使得 “类型相关信息” 在编译期可用通过重载技术overloading实现在编译期对类型执行 if...else 测试)
48. 认识 template 元编程模板元编程TMPtemplate metaprogramming可将工作由运行期移往编译期因此得以实现早期错误侦测和更高的执行效率TMP 可被用来生成 “给予政策选择组合”based on combinations of policy choices的客户定制代码也可用来避免生成对某些特殊类型并不适合的代码
49. 了解 new-handler 的行为set\_new\_handler 允许客户指定一个在内存分配无法获得满足时被调用的函数nothrow new 是一个颇具局限的工具因为它只适用于内存分配operator new后继的构造函数调用还是可能抛出异常
### Google C++ Style Guide