Effective C++ 索引

《Effective C++》 由Scott Meyers 编写,是从初级C++程序员向高级进阶的桥梁,特别适合C++的初学者,或者准备面试的程序员,这本书中讲的全部是资深程序员的经验和技巧,对C++的工程应用有着很大的帮助。读了这本书,你将会理解工程源码中一些奇怪的处理。费时一个多月读完了这本书,下面是汇总的目录。

注:其中第25条讲了模板和派生类中对函数名的遮掩,第35条提到了Strategy模式,第45条讲了成员函数模板的注意事项,第49条讲了new_handler的使用技巧,这几条涉及概念比较多,需要仔细梳理。搞明白以后对C++的使用会有更加深刻地认识。

习惯C++

  1. C++ 是一个语言联邦
  2. 尽量使用 inline enum const 代替#define
  3. 尽可能使用 const
  4. 确定对象使用前已经被初始化

构造,析构,赋值

  1. 了解C++默默编写了哪些函数
  2. 如果不想用编译器自动生成的函数,就明确拒绝
  3. 为带多态性质的基类设计 virtual 析构函数
  4. 析构函数绝对不要吐出异常,要么在析构函数中处理,要么在类的普通函数中丢给用户
  5. 不要在构造和析构函数中调用虚函数
  6. 令赋值操作符返回一个*this指针,使其实现连锁形式
  7. 在赋值操作符中考虑自我赋值以及异常安全,可以使用copy and swap 技术
  8. 复制对象时需要复制每一个成分,并且复制构造函数和赋值操作符不能相互调用

资源管理

  1. 使用对象管理资源,使用auto_ptr, tr1:shared_prt 等类指针对象
  2. 注意资源管理对象的copy行为,根据所管理的对象特点选择不同的方案:禁止复制或者计数复制
  3. 在资源管理对象中保留对原始对象的访问,可以使用显式转换或者隐式转换
  4. 成对使用new 和 delete 时使用相同的形式:数组形式的 new 需要调用 delete[]
  5. 以独立语句将 newed 指针置入智能指针,由于编译器会对同一语句中的操作进行重新排序

接口编写

  1. 使你的接口不容易被误用,传递指针时多使用类指针对象,传入多个形参时使用类
  2. 设计class就像设计type,这是类设计过程中需要注意的一系列要点
  3. 传递形参时多使用引用而非值,传递引用可防止对象被切割
  4. 函数的返回值,不能是对象的引用
  5. 成员变量设置为private,可以保证数据访问一致性,细微划分访问控制,允诺约束条件得以保证
  6. 尽可能使用non-member和non-member函数替代member函数,以此保证最好的封装性
  7. 所有参数均需要类型转换,采用non-member函数
  8. 写没有异常抛出的swap函数,要替代系统自带的swap函数时,需要写多个 member,non-member,特化swap

实现

  1. 尽可能延后变量定义式的出现,直到他可以被初始化,循环中为了提高封装性,应该把变量赋值放在循环体内
  2. 尽量少做转型,特别是开销巨大的dynamic_cast,多使用C++的转型而非C的旧转型
  3. 避免返回handle指向对象内部,避免指针指向空的地址,典型例子就是vector返回对象的引用
  4. 异常安全函数提三种保证之一:基本保证,强烈保证,不抛出异常
  5. 谨慎使用inline,他会导致代码膨胀,会给程序升级带来难度,指针调用的函数不会被inline
  6. 将文件编译依存度降低,通过分离声明和定义,有handle class和interface class两种方式

继承与面向对象设计

  1. 使用public继承描述is-a关系:但是“鸟-企鹅”、“长方形-正方形”等常识关系并不满足继承关系,因为派生类不一定适用基类的方法
  2. 不要隐藏继承而来的名称
  3. 区分接口继承与实现继承:使用protect函数来实现默认功能
  4. 虚函数以外的方法:NVI和Strategy模式(使用另外一个继承体系的虚函数)
  5. 绝对不要重新定义继承来的非虚函数
  6. 绝不重新定义继承而来的缺省参数,非虚函数一定不要改变,虚函数的缺省参数也不要改变,会导致调用中调用基类的缺省参数
  7. 通过复用表示has-a关系和根据某物实现
  8. 明智而审慎的使用private继承,可以产生空基类空间最优
  9. 明智而审慎的使用多重继承,多重继承比较复杂,并且会带来额外的开销

模板与泛型编程

  1. 了解隐式接口和编译期多态,模板对数据类型的要求也是一种接口
  2. typename的双重含义:一种在模板声明语句中跟class等价,一种用来声明内嵌从属类型
  3. 学习处理模板化内基类内的名称:使用this指针指出,或在函数内声明,否则编译器不会进入模板化内基类进行查找
  4. 将与参数无关的代码抽离templates
  5. 运用成员函数模板兼容所有可接受类型
  6. 需要类型转换时提供非成员模板函数,但是需要声明为友元
  7. 使用trait class表现类型信息
  8. 认识TMP模板元编程,可以在编译期查出程序错误

定制new和delete

  1. 了解new_handler的行为,new失败时会不断调用new_handler函数,可以为自己的类定义独自的new_handler函数,也可以使用模板类来实现
  2. 了解new和delete合理的替换时机
  3. 编写new和delete时需要固守常规,new需要循环调用new_handler,new需要处理0byte请求,delete需要处理空指针,此外还需要应对继承带来的尺寸问题
  4. 写了placement new也需要写placement delete,类中但凡定义一种new,就会掩盖所有的global new

杂项讨论

  1. 不要轻易忽视编译器的警告,不可过分依赖警告,因为不同编译器的警告标准不同
  2. 熟悉tr1在内的标准程序库
  3. 熟悉boost
发布了4 篇原创文章 · 获赞 0 · 访问量 14

猜你喜欢

转载自blog.csdn.net/yu_xiaoxian_2018/article/details/105326205