1.视C++是一个联邦语言。由C,Object-Oriented C++,Templete C++,和STL组成。其中面对不同的语言,采用不同的规约这样编程效率会提高很多。例如C和STL 都是有C-Style 的指针塑造出来的,所以采用Pass-by-value 比较适用。而Object-Oriented C++和Templete C++则采用pass-by-reference-to-const比较好。
2.尽量以const,enum,inline 替换#define。
//#define->const //原因: #define MAXNUM 100 若MaxNum出错,则编译器只会显示100这个魔鬼数字。(什么是魔鬼数字详见《C++ Primer》),因为define定义的记号不会被编译器看见。 synbol table不会记下MaxNum这个符号。所以如果在一个庞大的工程中,再根据一个魔鬼数字来寻找出错的地方。 --很蛋疼。 而const不一样。 const int MAXNUM=100; const定义的常量是会进入symbol table的,查找错误也变得更加清晰。
//#define->enum //原因 想过一个问题没有。C++怎么实现在类中(in-class)实现常量的定义。用static?NO~很多旧的编译器不支持~ 对,可以用enum,例如 class Week { enum{SUN,MON,....}//星期一到星期天 //还有,enum定义的是常量,不是变量,所以在以后的代码中也不可以去改变。 }
//#define->inline //原因 #define MAX_CALL(a,b) f((a)>(b)?(a)(b))//根据a,b大小来确定调用f(a)和f(b),明显不好。 改为inline(内联函数)函数。 template<typename T> inline void MAX_CALL(const T&a,const T&b) { f(a>b?a:b); } //总结:单纯的常量可以用const和enum来替换掉#define,而函数宏可以用inline内联函数来替换#define //当然。#define之类的预处理器还没有完全被完全抛弃。
3.尽可能使用const。
//STL是根据C语言的指针塑造出来的。所以声明const std::vector<int>::iterator iter=vec.begin(); //实质是声明了T *const,这个是const-pointer non-const-value。若想声明一个const-value的迭代器,那么 //你需要的是const_iterator.
std::vector<int> ivec; ...... const std::vector<int>::iterator iter = ivec.begin(); *iter=100;//OK 因为T const *,是const-pointer; ++iter// 错误。
std::vector<int>::const_iterator cIter = ivec.begin(); *iter=100;//错误,因为是const T *,是const-value; ++iter//OK。
令函数返回一个常量值。往往可以降低因为客户的低级错误而造成的意外,又不至于放弃安全性和高效性。
class cMath{....} const cMath operator *(const cMath &lhs,const cMath &rhs) { ... }
cMath a,b,c; if(a*b = c)//万一写成这样?不会报错哦。
关于bitwise-constness 和 logical-constness都不再这里赘述,有兴趣可以自己去看看这两个理论。