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

本文讨论了在C++编程中为何应该用const、enum和inline替换#define。const提供了更好的编译错误追踪和封装性,enum限制了作用域并避免了取地址的错误,而inline函数解决了宏的类型安全和效率问题。建议尽量遵循这些最佳实践。
摘要由CSDN通过智能技术生成

一、用const替换#define

 
  #define 存在以下的问题:

1. 发生编译错误时,很难追踪

#define PI 3.14		

 
  如果运用了上面定义的常量时,由于在预编译时,所以用到了PI的地方全部都已经被替换掉了,若发生编译错误,错误信息只会提到3.14,而不是PI,非常的难以追踪。
  解决方法就是用常量替换#define

	const double PI = 3.14;			//则替换了#define
	const double* const PI = 3.14;	//若是使用指针需要const两次
	*PI = 3.1415926;				//这就会报错,原因条款三说明
	double i = 2.12;
	PI = &i;						//这也会报错

2.没有封装性,不能限制作用域

 
  若想创建class专属常量,无法用#define创建,因为它的作用域并没有限制,一旦宏被定义,就一直有效(除非去#undef),因此使用const常量,只要将其作用域限制于class内(即让它成为class的一个成员),而为了让它只有一份实体,让它成为一个static成员。

class GamePlayer
{
	private:
		static const int NumTurns = 5;	//静态常量声明式,所有实例共享
		static const int Num;			//静态常量声明式
		int scores[NumTurns];			//使用上面定义的常量
}
#include "gameplayer.h"

	const int GamePlayer::Num = 5;			//Num定义式,在实现文件中

 
  上面的常量NumTurns是声明式而非定义式,而对于一般的staic变量(Num),是在头文件中声明它是static,而在源文件中定义的;而对于static const变量,假如这个变量是“整数”类型:int,char,bool,那么直接就可以直接声明,而不用定义。

二、用enum代替#define

 
  在上面用作数组大小时,用const代替,若不想让别人获得一个指针或印用指向该常量时,enum就可以实现这个约束条件。

class GamePlayer
{
	private:
		enum { NumTurns = 5 };			//enum,令NumTurns成为5的一个标记
		int scores[NumTurns];
}

 
  取enum的地址是不合法的,而取const的地址确是合法的,因此认识enum是有必要的。而这也是template metaprogramming(模板元编程)的基础技术。

三、用inline代替#define

 
  当用#define实现宏时,宏看起来像函数,但不会招致函数调用带来的额外开销。

#include <iostream>
using namespace std;
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))

int main()
{
	int a = 5, b = 0;
	CALL_WITH_MAX(a++, b);			//a累加两次
	CALL_WITH_MAX(a++, b++);		//a累加一次
	return 0;
}

 
  在上面的main函数中,宏中的两个实参较大值调用函数 f (),调用宏时,a的递增次数竟然取决于a和b的大小;并且类型是否相同,也没有检查。
  而使用template inline函数,则可以解决上述问题。

template<typename T>					
inline void callWithMax(const T& a, const T& b){
	f(a > b ? a : b);				//因为不确定a, b的类型,用模板编程
}

四、请记住

 

  • 对于单纯常量,最好以const对象或enums替换#defines。
  • 对于形似函数的宏,最好改用inline函数替换#defines。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值