C++学习笔记--尽量以const,enum,inline替换#define

本文内容整理自《Effective C++ 》中文版,主要讲述 C++ 中在一些场合使用 const、enum、inline 来替换 #define 所带来的好处。

1、const

当我们编写这样一条代码:

#define ASPECT_RATIO 1.653

由于记号名称 ASPECT_RATIO 也许从未被编译器看见;也许在编译器开始处理源码之前就被预处理器移走了,所以可能会出现以下问题。当你运用该常量时出现编译错误信息,但该错误可能提到的是1.653而不是 ASPECT_RATIO,甚至当 ASPECT_RATIO 被定义在他人所写的头文件中时,你对1.653以及它的来处毫无概念,导致你会因为追踪它而浪费时间。

解决办法:以一个常量来替换该宏:const double AspectRatio = 1.653;

AspectRatio作为语言常量,AspectRatio 肯定会被编译器看到。此外对浮点常量而言,使用常量可能比使用 #define 导致较小的码,因为预处理器“盲目地将宏名称 ASPECT_RATIO 替换为1.653”可能导致目标码出现多份1.653,而使用常量 AspectRatio 绝不会出现该情况。

特殊情况:

 常量指针:由于常量定义式通常被放在头文件中,因此有必要将指针声明为 const。如果要在头文件里定义一个常量的字符串,必须写 const 两次:const char* const authorName = “Scott Meyers”;

在C++中,string 对象通常比 char* 合适,所以上面可以定义为这样更好:

const std::string authorName(“Scott Meyers”);

class 专属常量:为了将常量的作用于限制在class内,必须让它作为class的一个成员,为了确保其最多只有一份实体,必须让它成为static 成员:

class GamePlayer

{

private:

           static const int NumTurns = 5;//此为声明式,而非定义式

           int scores[Numturns];

};

当你取某个class专属常量的地址,或者某些编译器坚持要看到一个定义式,你应在实现文件(非头文件)中放入下式:

const int GamePlayer::NumTurns;

由于class常量已在声明时获得初值,所以在定义时不再设初值。而对于有些旧式编译器不支持static成员在声明式上获得初值,你可以将初值在定义式上。

2、enum

当你在class编译期间需要一个class常量值,例如上述的数组声明式中若坚持必须在编译时获得数组大小。而你的编译器又出现不支持static成员在声明式上获得初值的情况,可改用所谓的“the enum hack”补偿做法。于是定义如下:

class GamePlayer

{

private:

          enum { NumTurns = 5 };

           int scores[Numturns];

};

此外,如果不想别人获得一个 pointer 或 reference 指向你的某个整型常量,enum 是一个好的选择,而且对于优秀的编译器不会为“整数型 const 对象”设定另外的存储空间,但有些不够优秀的编译器可能会,但对于 enum 会和 #define 一样绝不会导致非必要的内存。

3、inline

看以下例子,宏夹带宏实参,调用函数f:

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

即使你像上面那样为所有的实参都加上了小括号,但看下面情况:

int a = 5,b = 0;

CALL_WITH_MAX(++a,b); //a 被累加了两次

CALL_WITH_MAX(++a,b+10); //a 被累加了一次

在这里,调用 f 之前,a 的递增次数竟然取决于“它被拿来和谁比较”!

C++ 中,你可以获得宏带来的效率以及一般函数的所有可预料行为和类型安全性--只要你写出 template inline 函数:

template

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

{

    f(a > b?a:b)

}

当然,f 函数定义时也要使用模板。

这样,上述的问题都将被解决,此外由于 callWithMax 是一个真正的函数,它遵守作用域和访问规则。

总结:对于单纯常量,最好以 const 对象或 enum 替换 #define。

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

你可能感兴趣的:(C++,C++,const,enum,inline)