尽量以const、enum、inline替换#define(编译器替换预处理器)

一、中心内容:

1、对于单纯常量,最好以const对象或enums替换#defines;

2、对于形似函数的宏,最好改用inline函数替换#define。

二、简述

(1)const和#define

e.g 

#define ASPECT_RATIO 1.653;             改为   

const double AspectRatio =  1.653;//大写名称通常用于宏

1、前者的ASPECT_RATIO符号可能在开始处理源码前就被预处理器移走了,而没有进入记号表;

2、后者const是一个语言常量,绝对会进入符号表

3、两种特殊情况:

1)定义常量指针(常放在头文件中)

必须写两次const:

const char* const authorName =  "Scott Meyers";   改为

const std::string authorName("Scott Meyers");//string对象更合时宜

2)class专属常量

为了将常量的作用域限制于class内,必须成为class的一个成员;

为确保只有一个实体,必须使他成为class的一个static成员。

class GamePlayer{

private:

    static const int NumTurns = 5;

    ...

}

note:

由于C++要求所使用的任何东西都得提供一个定义式,而上述只是声明,so:

const int GamePlayer::NumTurns;//由于声明是已经提供了初值,所以不再赋值。


另外,由于#define并不重视作用域,一旦定义,之后编译中均有效,所以其不能用来定义class专属常量,也不能提供任何诸如 private #define 之类的封装特性。


通常情况下,不允许static成员在声明式子上获得初值(除了整数常量),这时候常常放在定义式中。


(3)#define和enum

特殊情况,当class编译期间需要一个class的常量值,例如定义一个数组必须知道其数组的大小时,但编译器又不允许完成“in_class初值设定”,可以改用enum。

即:

class GamePlayer{

private:

    enum{ NumTurns = 5};

    int scores[Numeturns];

    ...

};

用enum的理由如下:

1)在某方面来说等价于#define:

例如:取一个const的地址是合法的但是取一个enum和define的 地址是不合法的,这就可以避免别的用户获得一个指针/引用指向你定义的整数常量;

2)enum或define在所有编译器中可以避免非必要的内存分配,即分配内存。


(3)#define和inline

有时候为避免额外开销,将短小、简单的函数定义成宏,如:

#define   CALL_WITH_MAX(a, b)   f((a) > (b) ? (a) : (b));

形如这种形式的宏有许多的缺点:

e.g

int a = 5, b = o;

CALL_WITH_MAX(++a, b) ;//会导致a累加两次

CALL_WITH_MAX(++a, b+10); //导致a累加一次

即,a的递增次数取决与其的比较对象的大小。


为避免这种情况的发生,可以用template inline函数来代替:

template <typname T>

inline void callWithMax(const T& a,  const T& b)

{

    f(a>b ? a:b);

}


note:

遵守作用域和访问规则。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值