Effective C++ 读书笔记——条款2:尽量以const,enum,inline替换#define

 
中“宁可以编译器替换预处理”算是另一种提法,不过这个应该是概括性的说法吧
主要事项注意如下:
1用const double AspectRatio=1.653;代替#define ASPECT_RATIO  1.653
  原因是预编译时define会被简单的替换,这样在编译时丢掉了ASPECT_RATIO,如果不正
  当使用了ASPECT_RATIO编译时提示出错的可能只是1.653,这时候查找起来麻烦多了
另一个原因是定义成变量后编译时只有一份拷贝,节约了代码
当然这个条款也有特例
1)当出现指针的时候要这样
constchar*constautherName ="Scott Mayers";
即指针和其内容都不可变,当然如果是字符串string会比上面的char更合适
const std::string autherName("Scott Mayers");
2)注意class的专属常量,通过使得常量成为class的一个member将常量作用域限制在class内,而#defnie做不到。
通过使用static使常量只有一份拷贝
classGamePlayer(){
private:
staticconstintNumTurns = 5;
intscores[NumerTurns];
……
};
但上面给出的是声明而非定义,通常C++要求对任何东西的使用都要有定义式,但
像这种情况则可以例外,只要不取他们的地址就可以。
如果取地址,或者因为编译器的原因要求定义式,这定义如下:
constintGamePlayer::NumTurns;//将此式放进一个实现文件而非头文件
class常量已经声明了初值,这里就不在设了。
旧的编译器可能不支持以上语法,那么你可以把初值放在定义式中。
这又有例外了,编译器期间需要一个calss常量时(如数组scores[]的声明式),编译器又不允许“static整数型class常量”完成“in class”初值设定,可以改用“the enum hack”来实现。
classGamePlayer {
private:
  enum{ NumTurns = 5 };
  intscores[NumTurns];
……
}
emum hack的方法其实和#define又有些像了,例如不能取得地址,如果不想让人获得地址或者reference这样正好。另外Enmus和,#define绝不会导致不必要的内存分配(为什么这么说?难道编译器不会为Enmus分配内存?#define不知在每次调用都会占一次内存吗?const只有一份拷贝,不管调用多少次,难道const比define还多费了内存??)
3)回到预处理器来,另一个常见的#define误用情况是以它实现宏(macros)。
宏看起来像函数,但不会招致函数调用(function call)带来的额外开销。
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))
无论何时当你写出这种宏,必须记住为宏中的所有实参加上小括号,即使是加了括号,也还是会有问题。如
int a = 5, b = 0; 
CALL_WITH_MAX(++a, b);      //a被累加二次 
CALL_WITH_MAX(++a, b+10);   //a被累加一次在这里,调用f之前,a的递增次数竟然取决于"它被拿来和谁比较"!
用inline函数来解决这个问题
template inline函数(见条款30):

template<typenameT>                   //由于我们不知道具体会操作什么类型,所以用模板 
inlinevoidcallWithMax(constT& a,constT& b) //T是什么,所以采用 
{                               //pass by reference-to-const. 
  f(a > b ? a : b);                  //见条款20. 
}

对于单纯常量,最好以const对象或enums替换#defines。
对于形似函数的宏(macros),最好改用inline函数替换#defines
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值