再读Effective C++

Effective C++ 笔记

10年后再读Effective C++ 3rd(English),没有对细节的追问,更多的是对C++设计思路的思考,各章节标题为是个章节的概括和总结

让自己习惯C++

  • C++由多个部分构成

    C, Object-Oriented, Template, STL  
    
  • 尽量多的使用const,enums,inline代替define

    更好的静态检查
    
  • 尽量多用const

    不仅是防御式编程,更重要的是再检验设计的合理性
    
  • RAII 资源获取即初始化

    c++编程里永不过时的一句,无论声明一个变量或者获得某种资源      
    

默认生成的函数们

  • 留意C++自动生成的代码:构造,析构,copy构造,operator =

    自动生成代码运行的机制,绝对是笔试,面试中的常客
    
  • 如果不需要,就显式的禁用自动生成的代码

    各种笔试,面试经常出现只能栈上分配,堆上分配,不能继承,不能copy等等都是变种
    
  • 多态基类的析构必须是虚函数

    毋庸置疑,C++派生规则中必须遵守的一条,简单粗暴点就是基类的析构一定是虚函数
    
  • 析构函数不要抛异常

    抛了异常就会导致析构传递断裂,资源泄漏在所难免
    
  • 构造/析构中不要调用虚函数

    笔试,面试中经常出现
    
  • operator = 返回 *this

    链式使用不可少
    
  • 处理好operator = 自赋值

    同样经典,必不可少
    
  • 拷贝构造一定要拷贝全

    不要为什么,如果copy少了,必须是copy错了
    

资源管理

  • 使用对象管理资源

    3年经验的必须懂
    
  • 资源管理类的copy行为要慎重

  • 资源管理类提供访问Raw-Resource的方法

    std::string::c_cstr()要明白
    
  • new/delete 形式要对应

    new <=> delete, new [] <=> delete []
    
  • 存储new分配的资源在smart pointer中单独处理

    void foo(tr1::shared_ptr<Data> obj);
    foo(new data); // wrong
    tr1::shared_ptr<Data> pd (new Data());
    foo(pd); // all right
    

设计和声明

  • 接口好用不易错

    类型转换处理好
    语意上自然
    
  • 类设计就是类型设计

    类设计的基本规则之一
    
  • 常引用传递代替值传递

    不仅减少对象生成消亡的开销,还可以简化代码
    
  • 该返回对象时,勿返回引用

    c++不是java,没有天生的引用计数机制
    
  • 数据成员私有

    多一层保护多一层自由,要不C#也不会搞属性,Java搞setter/getter出来
    
  • 使用非成员,非友元函数替代成员函数

    增强封装,弹性以及功能扩展,简单的说,不必要的不要放在内部
    
  • 当参数都需要类型变化时,声明为非成员函数

    负数类operator + , 如果可以接受 int,char,double那么就声明为非成员函数,大家都开心
    
  • 支持无异常交换

    swap很重要,无论是在拷贝构造还是赋值运算中
    

实现

  • 尽量推迟变量的定义

    首先你要弄清楚什么是定义,哈哈
    
  • 最小化CAST

    尽量不用,尤其是dynamic_cast,必须用的时候尽量封装到函数里,优先C++ style, no C
    
  • 避免返回对象的内部处理细节

    对于这样的代码情何以堪:
    const Rect r(left, up, right, down);
    rect.getLeftup().setX(x);
    另外,临时对象也很难hold住
    
  • 异常安全

    这个怎么说都不过分
    
  • 明白inline函数的输入输出

    內联函数短小精悍,二进制升级要考虑好。
    
  • 最小化文件编译依赖

    现在的代码似乎根本不在乎这一套     
    

继承和面向对象设计

  • 继承要符合“is-a”模型

    关键在于怎么理解企鹅是鸟不会飞这样的无厘头
    
  • 避免隐藏继承来的名字

    这个就是所谓的“隐藏规则”,笔试,面试都会有
    
  • 区别接口继承和实现继承

    virtual的都要设计成接口,非虚的都是实现
    
  • 考虑虚函数以外的其他选择

    解决问题的方法不止一个     
    
  • 绝不重新定义继承而来的非虚函数

    C++就是这样,虚与实之间的界限有时清晰有时晦涩
    
  • 绝不重新定义继承而来的有默认参数的函数

    c++默认参数静态绑定
    
  • 使用组合来表示“A包含B”、“A以B的形式实现”

    弄清楚AB的关系比什么都重要
    
  • 明智的使用私有继承

    私有继承意味着全部都不能继续继承了
    
  • 明智的使用多继承

    单继承多实现是个好主意
    

模版和范型

  • 理解隐式接口,编译期多态

    理解接口,理解编译期多态,理解万岁
    
  • 理解typename的两个含义

    1:和class一样在模版中,2:表示后面是一个类型
    
  • 如何访问模板化基类中的名字

    1:this, 2:using 3:fullname
    
  • 把与参数无关的代码抽离templates

    模版生成代码膨胀要注意
    
  • 模版函数尽量多的兼容类型

    多多益善
    
  • 需要类型转换时请为模板定义非成员函数

    放在里面很别扭
    
  • 使用traits classes表现类型信息

    典型的函数式思路和STL实现
    
  • 了解模版元编程

    运行期放到编译期
    

自定义new和delete

  • 理解new-handler

    new的内部细节
    
  • 理解替换new和delete的时机

    没有特别的理由无需重载
    
  • 按照约定实现new和delete

    new和delete都有自己的格式
    
  • 放置new和放置delete

    new和delete一定要对应
    

你可能感兴趣的:(C++,C++,总结,技巧,笔记,effective)