本节主要讲define的两个用法:## 和 宏展开
1. ##
##的作用是连接两个参数。例如对于下面的宏定义
#define CONCAT(X, Y) X##Y调用将得到ab:
CONCAT(a,b)有什么高级用法呢?可以自动生成类
#define AUTO_GEN_CLASS(Name)\
class Name\
{\
public:\
Name(){}\
int m_##Name;\
};如果调用
AUTO_GEN_CLASS(A)就有了有成员m_A的类A
进一步引申,可以自动生成一个Singleton
#define AUTO_GEN_SINGLETON(Name)\
class Name\
{\
public:\
static Name* getInst()\
{\
static Name m_##Name##_inst;\
return &m_##Name##_inst;\
}\
private:\
Name(){}\
};这样,AUTO_GEN_SINGLETON(B)就可以得到单例类B了
有时我们想自定义类,这样有AUTO_GEN_SINGLETON的高级版:
#define SINGLETON(Name) \
public:\
static Name* getInst()\
{\
static Name m_##Name##_inst;\
return &m_##Name##_inst;\
}\
private:\
Name(){}\定义类C:
class C
{
SINGLETON(C)
public:
int getXXX(){return 1;}
};使用:
C::getInst()->getXXX();
2. 宏展开
如果我们定义了
#define ZERO 0
那么当调用时,会得到aZERO,并不是我们想要的a0
CONCAT(a, ZERO)
这是因为##不会自动展开,我们需要增加一个中间层#define CONCAT(X, Y) _CONCAT(X, Y)
#define _CONCAT(X, Y) X##Y这样,调用CONCAT(a, ZERO)后,所有参数将在转换层_CONCAT中展开:_CONCAT(a, 0)
再用a0替换
本文介绍了C/C++预处理器中的两个重要特性:##操作符用于连接标识符和宏展开。通过示例展示了如何利用这些特性来自动生成类和单例模式,以及解决宏展开时的问题。
9355

被折叠的 条评论
为什么被折叠?



