条款02: 尽量以const,enum,inline替换 #define

条款或许改为“宁可以编译器替换预处理”更好,因为或许#define不被视为语言的一部分。

对于如下的宏定义以常量替换:

#define ASPECT_RATIO 1.653

const double AspectRatio = 1.653;

原因:ASPECT_RATIO从未被编译器看到;你所使用的名称可能并未进入记号表(symbol table),作为语言常量AspectRatio肯定被编译器看到,当然也会进入记号表(symbol table)。对于浮点常量而言,使用常量可能比使用#define导致更小量的代码。

当以常量替换#define,又两种特殊情况:

1.定义常量指针,既要指针本身不变,又要指向的内容不改变,就要写两次const:

const char* const authorName = "Scott Meyers";	

或者用string来代替:

const std::string authorName = "Scott Meyers";	

2.class专属常量。为了将常量的作用域限制在class内,你必须让它成为class的一个成员;为了确保此常量只有一份,你必须让它成为static:

class GamePlayer
{
private:
	static const int NumTurns = 5;//常量声明
	int scores[NumTurns];
};	

const int GamePlayer::NumTurns;  //常量定义

若你编译器不支持在class声明的给常量初值,就把初值放在常量定义处。

对于上述的数组声明scores,编译器坚持必须在编译期间知道数组的下标大小。对于上述做法,另外一种做法就是使用枚举来当数组下标:

class GamePlayer
{
private:
	enum{NumTurns = 5};  	//枚举类型
	int scores[NumTurns];
	...
};	

对于枚举而言:第一,enum的行为比较像#define而不是const,你可以对一个const的取地址是合法的,但取enum的地址不合法,取#define的地址也不合法。你不想让别人像point或reference指向你的常量,enum可以帮你实现这个约束,此外,好的编译器不会为“整数型const对象”设定另外的存储空间,不够好的可能如此,enum和#define不会导致内存分配。

第二,纯粹为了实现主义,许多代码用来它,enum是模板元编程(template metaprograming)的基础。

对于使用#define误用情况以为它实现宏,宏看起来像函数,但不会导致函数调用带来的额外开销,并且会导致一般错误的宏调用。你可以使用template inline函数来替换。

 

有了const、enum和inline,我们对预处理器(特别是#define)的需求降低了,但并非完全消除。#include仍然是必需品,而#ifdef/#ifndef也继续扮演重要的角色。

总结:

  • 对于单纯常量,最好以const对象或enum替换#define。
  • 对于形似函数的宏,最好以inline函数替换#define。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值