本节主要讲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替换