Effective C++

术语
  1. explicit函数: 除非有一个好的理由允许构造函数被用于隐式类型转换,否则声明为explicit。
       2. c++不存在java和.NET中的接口概念
命名习惯
TR1和Boost
一、让自己习惯C++
  1. 视c++为一个语言联邦
    c++的主要次语言: c、Object-Oriented c++、Template C++、STL 
     2.  尽量以const,enum,inline替换#define(宁可以编译器替代预处理器)
         宏定义不会进入符号表,给调试带来麻烦
  •  对于单纯的常量,最好以const对象或enums替换#define
  • 对于形似函数的宏,最好改用inline函数替换#define
     3. 尽可能使用const
  • 将某些东西声明为const可以帮助编译器侦测出错误用法。const可被施加与任何作用域的对象、函数参数、函数返回类型、成员函数本体。
  • 编译器强制实施bitwise constness(意思成员变量存储的内容没有被改变),但当你编写程序的时候应该使用“概念上的常量性”(conceptual constness)。意思是如指针,不能让指针指向的变量内容变化,而不是只保持指向的变量不变,而不去管变量内容是否变化。
  • 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可以避免代码重复。本条还没有太读懂。
     4. 确定对象被使用之前已经被初始化 
  • 构造函数最好使用成员初始化,而不要在构造函数本体内使用赋值操作。
 
二、构造/析构/赋值运算
  1. 了解C++默默编写并调用哪些函数
  • 编译器会暗自创建default 构造函数、copy 构造函数、copy assignment 操作符、析构函数。
  1. 若不想使用编译器自动生成的函数,就该明确拒绝
  • 为了使编译器自动生成的函数不起作用,可以将相应的成员函数声明未private并且不实现,或者继承一个基类,这个基类中把要禁用的函数声明为private. (C++11中提供delete 函数,能够直接实现这一需求。)
  1. 为多态基类声明virtual析构函数
  • 需要被继承的基类应该有一个virtual析构函数。如果class带有任何的virtual函数,它就应该拥有一个virtual析构函数。
  • 如果一个类不是作为base class使用,就不该声明virtual析构函数。(虚函数表会导致类的内存变大)
     8. 别让异常逃离析构函数
  • 析构函数绝对不要吐出异常
     9. 绝不在构造和析构过程中调用virtual函数
     10. 令operator=返回一个reference to *this
     11. 在operator=中处理“自我赋值”
     12.赋值对象时勿忘其每一个成分
 
三、资源管理
   13. 以对象管理资源
     14. 在资源管理类中小心coping行为
     15. 在资源管理类中提供对原始资源的访问
     16. 成对使用new和delete时要采用相同形式
  • 注意指针数组的内存释放
  • 尽量不要对数组形式做typedefs动作
  • 尽量用容器代替数组
     17. 以独立语句将newed对象置入只能指针
 
 四、设计与声明
   18. 让接口容易被正确使用,不易被误用
  1. 设计classs犹如设计type
  2. 宁以pass-by-reference-to-const替代pass-by-value
  • 内置类型、STL的迭代器和函数对象除外
  1. 必须返回对象时,别妄想返回其reference
  1. 将成员变量声明为private
  2. 宁以non-member、non-friend替代member函数
  3. 若所有参数皆需类型转换,请为此采用non-member函数
  4. 考虑写出一个不抛异常的swap函数
 五、实现
  1. 尽可能延后变量定义式的出现时间
  1. 尽量少作转型动作
  2. 避免返回handle指向对象内部成分
        handle: reference、指针、迭代器
  1. 为“异常安全”而努力是值得的
  2. 透彻理解inlining的里里外外
  • 一个程序往往将80%的执行时间花在20%的代码上
  1. 将文件间的编译编译依存关系降至最低
六、继承与面向对象设计
  1. 确定你的public继承塑模出is-a关系
  • is-a, 是一个, derived是一个base , 反之不成立
  1. 避免遮掩继承而来的名称
  • 如果遮盖了基类中的函数名称,但是还是想用,只能用using
  1. 区分接口继承和实现继承
  • pure virtual: 只继承接口
  • simple virtual: 继承接口和一份缺省实现
  • non-virtual: 集成接口和一份强制实现
  1. 考虑virtualh函数以外的其他选择
  2. 绝不重新定义继承而来的non-virtual函数
  3. 绝不重新定义继承而来的缺省参数值
  4. 通过复合塑模出has-a或“根据某物实现出”
  • set的实现往往招致“每个元素耗用三个指针”的额外开销。因为sets通常以平衡查找树实现而成,使它们在查找、安插、移除元素是保证拥有对数时间效率,当速度比空间重要,这是个通情达理的设计。反之不然。
  1. 明智而审慎的使用private继承
  • 不是has-a, 是根据某物实现出。如果你用了private继承, 你的用意是为了采用子类的某些已经备妥的某些特性,不是因为drived和base有任何观念上的关系。
  1. 明智而审慎的使用多重继承
  1. 隐式接口和编译期多态
  1. 了解typename的双重意义
  2. 学习处理模板化积累内的名称
  3. 将与参数无关的代码抽离
  4. 运用成员函数模板接受所有兼容类型
  5. 需要类型转换时请为模板定义非成员函数
  6. 请使用traits classes表现类型信息
  7. 认识template元编程
  8. 了解new-handler的行为
  9. 了解new和delete的合理替换机制
  10. 编写new和delete时需要固守常规
  11. 写了placement new也要写placement delete
  12. 不要轻忽编译器的警告
  13. 让自己熟悉TR1在内的标准程序库
让自己熟悉boost
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值