02条款:尽量以const、enum、inline替换#define
define INT_A 5
const int a = 5;
const替换#define,const作为变量更能让编译器看见,从而加入记号表(symbol table),出现错误时可以更好查找出问题出处,加入了记号表则提示为a错误信息,未加入则提示5为错误信息。
且在定义类专属变量时,必须使用const,因为#define不具有任何封装性(除非在某处进行#undef)。
03条款:尽可能使用const
const成员函数不是百分百能控制函数体中变量不受改变;
在需要改变const成员函数中变量时,可以使用mutable进行操作;
1、将某些东西声明为const可以帮助编译器侦测出错误用法,const可用于任何作用域的对象、函数参数、函数返回类型、成员函数本体;
2、编译器强制实施bitwise constness(强制const,无法改变成员函数体变量机制),但编程时应该使用"概念上的常量性";
3、当const和non-const成员函数拥有实质相等的实现时,应该令non-const版本调用-const版本避免代码重复。
分享一下我之前网上看到的,如何判断const修饰的目标(不喜勿喷):
- const int *p;左边没有,看右边的一个,是int,自然就是p指针指向的值不能改变
- int const *p;此时左边有int,其实和上面一样,还是修饰的int
- int* const p :修饰的是*,指针不能改变
- const int *const p :第一个左边没有,所以修饰的是右边的int,第二个左边有,所以修饰的是 * ,因此指针和指针指向的值都不能改变
- const int const * p :这里两个修饰的都是int了,所以重复修饰了,有的编译器可以通过,但是会有警告,你重复修饰了,有的可能直接编译不过去
04条款:确定对象被使用前以及先被初始化
1、为内置型对象进行手动初始化,C++不保证会初始化他们;
2、构造函数最好使用成员初始化列表,避免在构造函数体中进行赋值操作,成员初始化列表应该按照声明顺序进行初始化
3、为了避免'跨编译单元的初始化序列'问题,请以局部静态对象(local static)替换全局静态对象(non-local static)。