您的位置:首页 > 编程语言 > C语言/C++

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

2017-09-07 10:07 561 查看

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

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

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: