宏函数

  #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 进去宏函数就行

你可能感兴趣的:(编程心得)