Effective C++读书笔记之尽量以const,enum,inline替换#define

     当使用#define定义常量时,如#define ASPECT_RATIO 1.653。由于#define是预处理命令,所以ASPECT_RATIO有可能没进入记号表(symbol table)内。因此在有关这个常量出错时,错误提示中没有ASPECT_RATIO记号,于是你将因为追踪它浪费时。解决之道是用const来替换上述的宏(#define): const double AspectRatio = 1.653;  这样AspectRatio会被编译器看到,当然会进入记号表中。
 当我们用常量替换#define时,有两种情况需要注意:
 1,定义常量指针(const pointers)  有必要将指针(而不是指针所指之物)声明为const,例如:
 const char * const authorNaem = "Scott Meyers";
 2,定义class的专属常量 #define无法创建一个class的专属常量 所以只能使用const,同时为了确保常量至多有一个实体,用static
 class GamePlayer{
 private:
  static const int NumTurns = 5;    //常量声明式  注意只有static整数型class常量才可以in class初值设定
  int scores[NumTurns];                 //使用该常量
 }; 
 注意上面的是NumTurns的声明式而非定义式,通常在头文件中。而有的编译器需要一个定义式,或者需要取它的地址,必须有定义式
 const int GamePlayer::NumTurns; //NumTurns的定义  因为在声明时赋值 这里不用赋值

        一些旧的编译器不允许static成员在其声明式上获得初值,或者这个class常量不是整型,则需要在定义式时给初值。例如:
 class CostEstimate{
 private:
  static const double FudgeFactor //static class 常量声明 在头文件中
 };
 const double CostEstimate::FudgeFactor = 1.35 //static class常量定义 在实现文件中
 
      唯一例外是当你在class编译时需要一个class常量,例如上面的GamePlayer::scores的数组声明式时,编译器需要知道数组的大小,而同时编译器不允许static整数型class常量完成in class初值设定,这时可使用"the enum hack",其理论基础是"一个属于枚举类型(enumerated type)的数值可权充ints使用",于是GamePlayer可定义为:
 class GamePlayer{
 private:
  enum {NumTurns = 5};    //"the enum hack"  令NumTurns成为5的一个记号名称
  int scores[NumTruns];  
 };
 认识enum hack  即不带实例的无标记enum
 1,enum hack的行为像#define 不像const 例如:可以对const取地址  可是不可以对enum 和 #define取地址
 2,许多代码使用了enum hack 所以需要认识它

        另一个常见的#define误用情况是以它实现宏(macros),宏看起来像函数,但不会带来函数调用的额外开销。上面是一个宏的例子:
 //以a 和 b 的较大值调用f
 #define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b)) //注要为每个参数加上括号
 这样使用有很多的缺点,最好是用inline替代 如下:
 template<typename T>
 inline void callWithMax(const T& a, const T& b)
 {
  f(a > b ? a : b);
 }
 也可以不使用模板函数。

 总结:
 1,对于单纯常量,最好以const对象或enums替换#define
 2,对于形似函数的宏(macros),最好改用inline函数替换#define
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值