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

本文详细解析了C++中常量的声明、定义、预处理器处理及注意事项,包括只声明不定义的特殊情况、如何正确取常量地址、类函数中使用#define的改进方法、以及避免宏误用的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)类似于

#define ASPECT_PATIO 1.653

的东西也许从未被编译器看见,在编译器开始处理源码之前也许就被预处理器移走了。ASPECT_PATIO没有进入记号表。如果该定义出现在不是本人写的头文件中,出现错误的话,编译器提示的错误信息也许提到:1.653,而不是ASPECT_PATIO。

       解决方法:

const double AspectRatio = 1.653;  

    这样的话,AspectRatio就肯定会被编译器看到,就肯定能进入记号表了!

(二)

const string authorName("Scott Meyers");  

往往比

const char* const authorName = "Scott Meyers";

要好

(三)

(1)

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

这种只声明不定义的方式是可以的,这是个特例:它是class专属常量又是static且为整数类型(ints, chars, bools),只要不取他们的地址,就可以像上面那样只声明不定义。
(2)如果我们要取该常量的地址,或者编译器坚持要看到它的定义式而报错的时候,那我们就必须提供定义式:
const int GamePlayer::NumTurns;该式子放进实现文件而不是头文件,因为NumTurns在声明的时候已经获得初值,所以现在定义的时候就不用再给初值了。
(3)旧式编译器不支持上述语法,如果我们编译器不支持static成员在声明式上获得初值的话,就这样改:

class CostEstimate {
private:
        static const double FudgeFactor;   //static常量声明
         ...                                //位于头文件内
};
const double CostEstimate::FudgeFactor = 1.35;     //static常量定义,位于实现文件内

(4)如果class编译的时候需要这个常量值,像下面这种情况!,这样的话,就不能用上面那种方法了,就必须用下面这种方法:

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

所以尽量用第四种方法!

(四)

取一个const的地址是合法的,但是取一个enum或者#define的地址就不合法了。

(五)写一个类似于函数的#define的话,一定要多用小括号!   

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

但是就算加了小括号也会出错:

int a = 5, b = 0;
CALL_WITH_MAX(++a, b);
CALL_WITH_MAX(++a, b+10);

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

所以用template inline函数代替:           

template<typename T>
inline coid callWithMax(const T& a, const T& b) {
     f(a > b ? a : b);
}

 

请记住:

(1)对于单纯变量,最好以const对象或enums替换#define。

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

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值