宏函数

  #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏,以下是宏的声明方式

#define name( parament-list ) stuff

  参数列表是由,隔开的一个符号表。 参数列表可带可不带,如果带参数列表的话必须与name紧邻否则会被解析成stuff的一部分。基于这个原理我们可以使用这个参数列表来实现函数。
  需要注意的是宏参数和#define定义可以包含其他#define定义的符号。但是,宏不可以出现递归。

#define M 9
#define PRINT( FORMAT, VALUE )    \
        printf("the value is  " FORMAT"\n" , M+VALUE);
int main()        
{
     PRINT("%d" ,M);
     return 0;
}

宏的特殊符号

  #与 ## 是俩个特殊符号,它们的含义如下

  1. # 表示将一个宏参数变成一个字符串
  2. ## 表把俩个字符串粘在一起
#define PRINT(VALUE) \
   printf(#VALUE);
#define STRCAT(str1,str2) \
      str1##str2
宏函数

宏函数在预处理的时候就会替换成相应的语句,十分像c++里面的模板。它的优点比正常函数更高效因为不用栈帧的开销,但是它的缺点就是1 没有类型检测 2 可能具有副作用 3可能导致代码量的增加这样会导致源文件变得更大4没有返回值。本文直接给出宏函数的应用。

应用
拷贝构造申请对象
#define  CHECK_AND_SET_OBJECT(obj,name,type)   \
   do  \
   {    \
      if(obj == NULL)  {  \
         printf("obj 为 NULL\n"); \
       } \
      type name(obj); \
   } while(0) 
           
标识形参

有的时候我们想知道这个函数声明的形参是输入参数还是输出参数,我们可以这样使用宏

#define IN
#define OUT
#define INOUT
void Fun( OUT  int * p); // p 为输出参数
void Fun2(IN int num); // num 为输入参数
巧妙的使用宏函数

有的时候可以把相关宏放头文件,通过增加头文件的宏,来修改代码,这个用法比较秀。如果下面这份代码,我们可以通过在Command.h中增加宏来改变 SomeThing.h 中 AllocHandler的逻辑,增加Get 则可以申请Get* 的数据,增加Set则可以申请Set* 的数据

Basic_Command.h 
Command_Header(Get)

Command.h
enum CommantType {
  ZERO = 0,
  #define Command_Header(Command) Command##_TYPE,
  #include "Basic_Command.h"
  #undef Command_Header
  MAXCOMMAND
};

SomeThing.h 
void AllocHandler(CommandType type)
{
#define Command_Header(Command) \
        if(Command##_TYPE == type) { \
           Handlers[type] = new Command##Handler(); 
        }
#include "Command.h"
#undef Command_Header
 return ;
} 

main.cc
#include "GetHandler.h"
#include "SomeThing.h"
int main() {
  AllocHandler(1);
  return 0;
} 
 
可变参数宏

宏可以简单的使用可变参数。只要在形参表最后一个加 … 即可。所有的可变参数使用__VA_ARGS__ 宏代替。 ## VA_ARGS 可消除 ## 前面的相应符号。如果不加##, LOG(“TEST”) 会被替换成 printf("%s:%d" “TEST”, func, LINE, ); ,从替换结果看多了一个 , 号。我们需要把这个 , 去掉所以得使用 ##去删除

LOG (format, ...)  \
         prinft ( "%s:%d"  format , __func__, __LINE__, ## __VA_ARGS__);
宏实现c++模板函数

如下面的实例宏 EXTERN_INSTANCE 就实现了模板函数 CreateInstance 和 DestroyInstance 函数。

MacroUtils.h
EXPORT_INSTANCE(type) \ 
void CreateInstance(type*& object) {
    object = new type();
}
void DestroyInstance(type*& object) {
    delete object;
    object = NULL;
}


main.cc
class A {
};
EXPORT_INSTANCE(A);
int main()
{
   A* p = NULL;
   CreateInstance(p);
   DestroyInstance(p);
   return 0;
 }
Linux 宏调试
  1. 增加编译选项 -g3
  2. gdb -> macro expand 具体宏
  3. step 进去宏函数就行
  • 18
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值