[effectiv c++]条款2:尽量以const,enum,inline替换#define(static,const定义式)

1、你所使用的名称可能并未进入记号表

#define ASPECT_RATIO 1.653 中的记号名称ASPECT_RATIO可能由于预处理器的处理,而未被真实编译器看见,于是记号名称未能进入记号表。

解决方法:用编译器替换预处理器
即用const替换宏(#define)
const double AspectRatio = 1.653
作为一个语言常量,AspectRatio一定会被编译器看到,当然会进入记号表内。

2、#defines不能用来定义class专属常量

因为#defines并不重视作用域,除非被#undef;
也不提供封装性,不存在private #define这种东西。

解决方法:使用static const
如果将常量的作用域(scope)限制于class内,必须让它成为class的一个成员(member)。如果要确保此常量至多有一份实体,必须让它成为static成员。

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

通常C++要求所使用的任何变量均需提供定义式,但如果它是一个class专属常量又是static且为整数类型(integral types, ints, chars, bools),则需特殊处理,只要不取它们的地址,可以只声明并使用它们而无需提供定义式;但如果你取某个class专属常量的地址,你就必须提供下面的定义式:
const int GamePlayer::NumTurns; // 定义

下面是static,const,static const 作为类成员的定义式的总结。
转自网友http://blog.csdn.net/livelylittlefish/article/details/5729894

类型类中(声明)类外(类实现文件)构造函数体中构造函数初始化列表
非静态非常量数据成员NNYY
非静态常量数据成员NNNY(must)
静态非常量数据成员NY(must)NN
静态常量数据成员YYNN
the enum hack

旧式编译器可能不支持在类中设定初值的语法(这是c++11的语法),可以将初值放在定义式。如果此时常量作为数组的大小,可以采用the enum hack补偿做法。其理论基础是:一个属于枚举类型(enumerated type)的数值可以权充ints被使用

class GamePlayer{
enum {NumTurns = 5};
int scores[NumTurns];
};

the enum hack的特点:

  • 无法取enum的地址,当你不想让别人获得一个pointer或reference指向你的某个整数常量时,enum可以实现
  • enum和#define不会导致非必要的内存分配

3、形似函数的宏的缺点

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

  • 必须为各个实参加括号
  • 对于自增运算符的bug

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

解决方法:template inline函数

template<typename T>
inline void callWithMax(const T& a, const T& b)
{
    f(a > b ? a : b);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值