改善程序与设计的55个具体做法--尽量以const等关键字,替换#define

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

#define ASPECT_RATIO 1.63

记号名称ASPECT_RATIO也许从未被编译器看见;也许在编译器开始处理源码之前它就被预处理器转移走了。于是记号名称ASPECT_RATIO有可能没进入记号表(sysbol table)内。于是当你运用此常量但获得一个编译错误信息时,可能会带来困惑,因为这个错误信息也许会提到1.653而不是ASPECT_TATIO。如果ASPECT_RATIO被定义在一个非你所写的头文件内,你就不知道它是什么。这个问题也可能出现在记号式调试器中,原因相同:你所使用的名称可能并未进入记号表。

解决之道是以一个常量替换上述的宏:const double AspectTatio = 1.653.

使用常量可能比使用#define导致较小量的代码,因为预处理器“盲目地将宏名称 ASPECT_RATIO替换为1.653”可能导致目标码出现多份1.653,若改用常量AspectRatio绝不会出现相同情况。

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

一、定义常量指针:由于常量定义式通常被放在头文件内(以便被不同的源码含入),因此有必要将指针(而不只是指针所指之物)声明为const,例如若要在头文件内定义一个常量char*-based字符串,你必须写const两次:const char* const authorName = "Scott Meyers";

eg: const std::string authorName(Scott Meyers);

二、class专属常量:为了将常量的作用域限制于class内,你必须让它成为class的一个成员(member);而为确保此常量至多只有一份实体,你必须让它成为一个static成员:

class GamePlayer{

private:

        static const int NumTurns =5;

        int scores[NumTurns ];

        ...

};

只要不取他们的地址,你可以声明并使用它们而无须提供定义式。但如果你取某个class专属常量的地址,或纵使你不取其地址而你的编译器却(不正确的)坚持要看到一个定义式,你就必须另外提供定义式:const int GamePlayer::NumTurns;

把这个式子放进一个实现文件而非头文件。由于class常量在声明时已经获得初始值,因此在定义时不可以再设置初始值。

我们无法利用#defines创建一个class专属常量,因为#defines并不重视作用域,也不提供任何封装性。

另一种写法:

class CostEstimate {

private:

        static const double FudgeFactor;

...

};

const double CostEstimate::FudgeFactor = 1.35;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lusir3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值