改变旧有的C习惯
C是一个单纯的语言,提供的是macros、pointer、struct、arrays和function.不论解决什么问题,答案总是由这5者构成。
C++可不一样,当然,上述五者仍存在,但还有private members、protected members,function overloading,default parameters,constructors,destructors,user-defined operators, inline functions, references, friend, template, exceptions, namespaces以及其它很多东西。
条款一:尽量以const、enum 和 inline 取代#define
尽量以编译器取代预处理器
例子一:
#define ASPECT_RATIO 1.653; const double ASPECT_RATIO = 1.653;
class GamePlayer { private: enum {NumTurns=5 }; //"the enum hack"--令NumTurns成为5的一个记号名称 int scores[NumTurns]; //... };
例子三:
对于宏定义的函数,会因为加入很多括号,看起来很麻烦,如:
#define max( a , b) f( (a) > (b) ? (a) : (b) )
就算写出来了,还有更奇葩的:
int a=5,b=0; max(++a,b); //a被累加二次 max(++a,b+10); //a被累加一次
使用inline函数,你便可以获得宏带来的高效率以及函数带来的可预期行为和引数型别检验。
inline int max(inta, int b) { reutrn a > b ? a : b; }
这与前述宏不完全相同,因为这个版本的max只接受int类型的参数,不过利用template可以修正这一问题:
template<class T> inline const T& max(const T& a, const T& b) { reutrn a > b ? a : b; }
☆对于单纯常量,最好以const对象或enums替换#defines。
☆对于形似函数的宏,最好改用inline函数替换#defines。
虽然如此,Inline函数虽然提高了效率,但是它也需要更多的内存。
条款二:尽量以<iostream> 取代 <stdio.h>
scanf和printf及其家族都还不够完美。尤其是他们都不具型别安全性质,也都不可扩充。由于型别安全和扩充性正是C++的基石之一。
一点也不惊讶,printf/scanf的弱点正是operator>>和operator<<的长处:
int i; Rational r; //r 是一个分数 cin>>i; cin>>r; cout<<i; cout<<r;
如果这段代码能够通过编译,一定是operator>>和operator<<能够为处理型别为Rational的对象。
针对一个用于表现分数(rational)的class,下面是你可能为它写的一个输出函数:
class Rational { public: Rational(int numerator = 0, int denominator = 1); private: int n, d; friend ostream& operator<<(ostream& s, const Rational& r); }; ostream& operator<<(ostream& s, const Rational& r) { s<<r.n<<'/'<<r.d; return s; }