条款1:尽量用const和inline(编译器)而不用#define(预处理)
理由:
1.#define(预处理)进入编译器之前预处理程序会将符号去掉,代以常量,在编译的时候报错信息指向常量而难以理解,定义一个const常量能很好的解决这个问题;
2.用#define来实现那些看起来象函数而又不会导致函数调用的宏:
#define max(a,b) ((a) > (b) ? (a) : (b)))
会导致一些奇怪的事情发生:
int a = 5, b = 0;
max(++a, b);// a 的值增加了2次
max(++a, b+10); // a 的值只增加了1次
这种情况下,max内部发生些什么取决于它比较的是什么值!一个替代的方法就是使用内联函数:
template<class T>
inline const T& max(const T& a, const T& b)
{ return a > b ? a : b; }
注意:
1、const定义指针常量时会,除了指针的指向类型要定义成const外,指针也常要定义成const(eg: const char * const authorName = "Scott Meyers";);
2、定义某个类的常量为了保证常量最多只有一份拷贝,还要把它定义为静态成员。
条款2:尽量用“iostream”而不用“stdio.h”
理由:
a.scanf/printf系列函数不是类型安全的,而且没有扩展性;它只能处理C下的那几种基本类型,比如int,float,char,double。而iostream里的>>和<<却可以通过重载支持任意类型。
class Rational {
public:
Rational(int numerator = 0, int denominator = 1);
...
private:
int n, d;// 分子,分母
friend ostream& operator<<(ostream& s, const Rational& );
};
ostream& operator<<(ostream& s, const Rational& r)
{
s<< r.n << '/' << r.d;
return s;
}
注意:
1、在形如"friend ostream& operator<<(ostream& s, const Rational& );"的重载时operator<<不是成员函数,而传递给operator<<的不是Rational对象,而是定义为const的对象的引用;
2、在一些特殊的实现内,iostream的操作实现起来比相应的C stream效率要低;
条款3:尽量用new和delete而不用malloc和free
理由:
malloc 和free(及其变体)不知道构造函数和析构函数,当使用malloc申请内存空间的时候,在内存中实际上并没有创建这些对象,而即使已经创建这些对象, 在释放的时候由于对象并不会调用析构函数,这些内存将丢失,而new和delete可以有效地与构造函数和析构函数交互。
注意:
new/delete和malloc/free不兼容,混用在一起回导致不可预测的结果,特别要注意一些函数内部到底使用malloc还是new分配内存的。
条款4:尽量使用C++风格的注释
理由:
在使用/**/嵌套注释的时候有可能会将注释提前结束。比如
if ( a > b ) {
/* int temp = a; /* swap a and b */
a = b;
b = temp;
*/
}
而使用行尾结束符//可以避免情况。
if ( a > b ) {
/* int temp = a; // swap a and b
a = b;
b = temp;
*/
}
注意:
老的专门为c写的预处理程序不知道处理c++风格的注释,所以象下面这种情形时,事情就不会象预想的那样:
#define light_speedp 3e8 // m/sec (in a vacuum)