Effective C++

实现

条款26: 尽可能的延后变量定义式出现时间

  • 定义变量后必然会有构造和析构的开销,过早定义变量可能导致我们没使用到其变量
  • 延后变量定义式,我们可以避免调用defualt构造,而是直接在构造时初始化

记住

  • 尽可能的延后定义式的出现。可以改善代码清晰度和效率

条款27: 尽量少做转型动作

记住

  • 尽量少用转型,特别注重效率的代码中,避免使用dynamic_casts
  • 尽量将转型动作隐藏在函数里面,客户调用函数不必将转型写入自己代码中
  • 使用C++style的转型方式

条款28: 避免返回handles指向对象内部成分

  • 导致const对象返回的handles,我们通过handles改变变量,违背const对象的初衷。这个我们可以对handles加上const来改善
  • 由于返回handles(大多指指针、引用,文件句柄等),会面临对象生命周期小于handles的风险
  • 事实上绝对不返回handles也不太实际,像是标准库里面很多模板类都有返回handles的函数

记住

  • 避免返回handles,遵守这个条规可增加封装性,帮助const成员行为想const,并将发生“虚吊号码牌”的可能性降低

条款28:为“异常安全”而努力是值的的

  • 异常安全指当程序抛出异常,我们需要保证不泄漏任何资源不允许数据败坏,对于不泄漏资源我们可以尝试使用智能指针的RAII特性管理资源
  • 由于系统内存如new或者其他运行环境原因,系统抛出异常是无法避免的,所以设计的时候不得不考虑异常安全

三个保证

异常安全的函数,需要满足三个保证之一

  • 基本承诺:如果异常,资源不泄漏,数据正常,但程序状态不可料
  • 强烈保证:如果异常,程序状态不改变,即程序回到“调用函数之前的状态”
  • 不抛掷保证:承诺绝不抛出异常,可以在函数后面添加noexpect关键字或throw()来保证不抛出异常

请记住

  • 异常安全函数能保证函数异常时数据不泄漏和数据正常,能将其区分为基本承诺强烈保证不抛掷保证
  • 强烈保证可以通过 copy-and-swap来实现。
  • 函数的异常安全强度,取决于函数及其调用函数中最弱的(木板效应)

条款31:将文件间的编译依存关系降至最低

  • C++将声明和实现分开实现,我们可以尽可能的在头文件里面将量少的链接其他文件,而是通过前置声明,在cpp文件里面去链接
  • 前置声明的条件需要头文件不包含该声明的定义,因为定义会涉及其默认构造函数实现,我们可以通过将其声明为指针来避免,或添加extern

记住

  • “依赖化最小”的基本思想是,相依于声明式,不要相依于定义式。
  • 程序头文件应该只有声明式的形式存在
最后修改:2023 年 01 月 10 日
如果觉得我的文章对你有用,请随意赞赏