本文章属于专栏- 概述 -《业界C++进阶建议整理》-CSDN博客
本文列出《Effective C++》的1-10条的个人理解的极精简版本。
- 01、c++是语言联邦
- 【c】 && 【c with class(继承多态、虚函数)】&& 【template c++】&& 【STL】
- 02、用const、enum、inline替换#define
- define在预处理环节,其声明的变量不会进入到符号表、也不会有类型检测
- 用宏定义的函数,不易阅读,且容易出错
- 03、尽量使用const
- c++对成员函数的const的定义是:const成员函数,不能改变对象中任意的non-static以及non-mutable的成员变量
- 个人见解:但是一些三方库的接口,接受参数不是const的,这个时候要传递参数,需要const_cast,而const_cast是模糊的,另外可能未来的三方库更新,会改变内容。所以要理解业务的参数的使用流程,才能知道哪些类适合const,而不是盲目的对不变的类使用const
- 04、确定对象被使用前已经被初始化
- 对象是否初始化的规则复杂,忘记这些规则,在每个对象使用前都初始化。使用构造函数的初始化列表更快、更安全。另class变量的初始化顺序是按照变量在class中声明的顺序,而不是初始化列表的顺序。
- 个人见解:对于一些系统关键的复杂类,一般只在程序启动的时候初始化一次,这个时候初始化列表中初始化,还是在构造函数体里面初始化,对效率影响不大,反而我们更关心初始化时可能出现的问题,需要更详细的初始化状态、日志,甚至异常。这一部分的初始化甚至不在构造函数,而是在另一个init函数中,以准确的知道这些复杂类的初始化详情。
- 05、c++默认编写的函数
- 对类,编译器会默认为其创造构造函数、析构函数、拷贝构造、拷贝赋值。所有这些函数是public且是online的
- 构造函数是初始化每个non-static的成员变量和base成员变量。
- 拷贝构造和拷贝赋值将non-static成员变量拷贝到目标对象
- 个人见解:只有当一个类没有定义任何拷贝相关的函数,且每个非static的数据成员都可以移动时,编译器才会合成移动构造函数。这个行为容易不可控,如果需要移动构造函数,请自己写。
- 对类,编译器会默认为其创造构造函数、析构函数、拷贝构造、拷贝赋值。所有这些函数是public且是online的
- 06、不想编译器自动生成的函数,就应该拒绝
- 要想不生成拷贝赋值和拷贝构造,可以继承一个拷贝赋值和拷贝构造为private的基类
- 07、为多态的基类声明virtual析构函数
- 在delete一个指向派生类的基类指针时,如果基类没有virtual析构函数,则不会调用派生类的析构函数
- 虚析构函数是有代价的,虚函数表是属于类的,但是虚函数指针是属于对象的
- 08、别让异常逃离析构函数
- 如果异常逃出,可能导致资源泄漏、数据处理不完备
- 09、绝不在构造和析构过程调用virtual函数
- 在构造和析构函数中,virtual函数不能从base层转到derive层,因为这个时候derive是没有的(还未创建或者已经被释放)
- 10、operator= 返回 reference to *this
- 为了连续赋值(如a = b = c =10;)
- 代码形式为:A& operator=(const A& rhs) { return *this}
- 个人见解:虽然operator=要返回*this,但是开发中,不要使用连续赋值,不易读,也不易debug,节省的代码量实在有限
- 为了连续赋值(如a = b = c =10;)