简介
C++是一个多重范型编程的语言,一个同时支持过程形式,面向对象形式,函数形式,泛型形式,元编程形式的语言,
可以把C++看成由四大子部分构成:C,Object-Oriented C++,Template C++,STL;
当我看完Effective c++之后,总是感觉有些书中写的极好的建议我就是想不起来,为了让之后想不起来时可以
随时查看,于是就想此时写一个读书笔记,方便之后的查阅!
正文
- 尽量以const,enum,inline替换#define ,因为#define只是由预处理器的字符串替换过程,我们所使用的名称并没有进入符号表当中,当出现问题时我们无法得知是哪个名称出问题;对于带参宏,我们也尽量以inline函数来替换,因为有些时候我们不一定会记得把所有的括号打上.
- 对于那些不应该被改变值的变量,我们尽量使用const来约束 ,如果在const成员函数内,有些成员变量的值也可能改变的话,可以把这些成员变量修饰成mutable.
- 确定对象被使用前已先被初始化 .我们应该尽可能的避免去读取未初始化的对象的值而产生不明确的行为.C++规定,对象的成员变量的初始化动作发生在构造函数本体之前,因此使用成员初值列表来对对象成员变量进行初始化是一个好做法.
- 了解C++默认为你编写并调用的那些函数 ,比如default构造函数,copy构造函数,析构函数(编译器产出的析构函数是个non-virtual,除非这个class的base class自身声明有virtual析构函数),copy assignment操作符等.
- 如果不想让编译器为你自动生成一些函数时,可以将这些成员函数声明为private并且不予以实现.
- 由于C++明确指出,当derived class对象经由一个base class指针被删除,而此base class带有一个non-virtual析构函数,其结果未定义.为消除此问题,我们可以给base class一个virtual析构函数,这样就可以通过delete基类指针来把derived class的对象成分全部销毁.
- 别让异常跳出析构函数,析构函数绝对不要吐出异常,如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们或结束程序.如果客户要对某个操作函数运行期间抛出的异常作出反应,那么class应该提供一个普通函数(而不是在析构函数中进行)执行此操作.
- 绝对不要在构造和构构过程中调用virtual函数,对象在derived class构造函数开始执行前不会成为一个derived对象.
- 令operator= 返回一个reference to *this.
- 在operator=中处理”自我赋值”.
- 成对使用new和delete时要采用相同形式.
- 以独立语句将newed对象置入智能指针.如果没这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏.
- 让接口容易被使用,不易被误用.
- 宁以pass-by-reference-to-const替换pass-by-value,这样可以大大降低开销.
- 必须返回对象时,别妄想返回其refrence.
- 将成员变量声明为private.
- 若所有参数皆要类型转换,请为此采用non-member函数.
- 尽可能延后变量定义式的出现时间.
- 尽量少做转型动作.
- 将文件间的编译依存关系降至最低.
- 避免遮掩继承而来的名称.如果想让被遮掩的父类函数名称重现的话,可以用using声明式或转交函数.
- 声明一个pure virtual函数的目的是为了让derived class只继承函数接口.声明一个非纯virtual函数的目的是让derived class 继承该函数的接口与缺省实现.
- 绝不重新定义继承而来的non-virtual函数.
- 绝不重新定义继承而来的缺省参数值.因为缺省参数值都是静态绑定的,而virtual函数却是动态绑定的.
- 明智而审慎地使用多重继承.
- 了解隐式接口和编译期多态.
- 了解typename的双重意义.
- 将与参数无关的代码抽离template.
- 不要轻易忽略编译器的warning.