《effective c++》条款二:尽量以enum,const,inline替换#define

以下,是对const,enum,inline的一系列测试

----《effective c++》条款二   :  尽量以const,enum,inline 替代#define

例如:

  #define PI 3.1415926

这个记号名称PI,也许不会被编译器所看到,也许在编译器开始处理源码之前它就被预处理器移走了。
于是在生成.o可重定义目标文件时,记号名称PI有可能没进入记号表(.symtab)内,当你运用此变量,
但获得一个编译错误信息的时候,错误也许会提到3.1415926而不是PI,
如果PI存在在不是你自己写的头文件中,你将非常难以对其进行追踪,进而浪费你的时间。
解决之道是以一个常量(const)替换上述的宏(#define):

  const double Pi = 3.1415926;  //  全大写名称通常用于宏定义

作为一个全局常量,这个变量必然会在编译的时候被计入记号表内
当要设置一个class的专属常量时,
为了将一个常量的作用域限制在一个class内,你必须让它成为一个class的成员(number):
而为了保证此常量只在内存中存在一个实体,
你应该让它成为一个static成员,如下:

 class A{
      private:
	     static const int Num = 12;  //常量声明式
		 int perple[Num];  
		 ...
  };

当然这只是个声明式,通常c++还需要你提供所使用的任何东西的定义式,
但如果它是个class专属static常量,且为整型,则可以声明并使用它而不需要提供声明式,
但是,如果你想在后面使用和访问这个整型常量的地址,则需要在.c(实现文件)文件中另外提供定义:

  const int A::Num;      // Num的定义

因为这个Num已经在生命中得到了初值,因此定义时不可以再设置初值
(只限制于整型,当然有些编译器也不支持整型在声明中赋予初值)
相反的,用#define则无法限制作用域,不能定义为一个class的专属常量,
也不能给一个class提供任何的封装性。如果你的编译器不支持上述语法,则可以将初值放在定义式:

  // A.h
  class A{
     private:
        static const int Num;  //static class常量声明
        int perple[Num];       //位于头文件内
        ...
  };

  //A.cpp
  const int              // static class常量定义
           A::Num = 12;  // 位于实现文件内    

如果你的编译器不支持使用“static 整数型 const 常量” 完成类中的数组长度设定,
可改用“the enum hack”补偿做法,因为一个属于枚举类型的数值可以被当作int const 使用”,于是上述代码可以定义如下:

class A{
       private:
           enum{ Num = 5};  
           int perple[Num]; 
            ...
   };

解决问题

当再次回到预处理器,另一个常见的#define误用情况是以它实现宏。宏看起来像函数,
但不会找只函数调用带来的额外开销,
下面一个宏带着宏实参,调用函数f , 如下:

  //记住为宏内所有的实参加上小括号
  #define CALL_MAX(a,b) f((a)>(b)?(a):(b)) 
    

但即便为所有实参加上小括号,还是会导致不可思议的事情:

  int a=5,b=5;
  CALL_MAX(++a,b);//a被累加一次
  CALL_MAX(++a,b+10);//a被累加两次
  

在这里,a的递增次数,竟然取决于“它和谁比较”
还好,你可以获得宏带来的效率,还可以避免出现以上的错误,
这要求你写出template inline(模版内联函数):

  template <typename T>
  inline void Call_Max(cont T& a,const T& b){
  f(a>b?a:b);

所以,综上所述,最好以const对象或enum替换#define
对于形似函数的宏,则最好以inline 函数替换。

以上

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值