C++宏定义小tips

宏定义


宏定义是C++编程中一种很常见的语法,有很多使用场景,例如

  • 定义一个通用的常量

  • 定义一个宏函数

  • 实现条件编译

  • 其他

第一种使用场景应该是最多的,一般格式如下:

#define PRICE 20

即定义了一个名为PRICE的宏,其值为20。需要注意的是,宏定义本身对C++编译器并不可见,它只是一条 预处理 指令,在预处理阶段,代码中多有的PRICE都会被替换成20。所以在一些编程书籍中,是不提倡使用宏定义来定义变量的,因为在编译出错时,报错信息不方便在代码中定位(上例中如果出错,可能不会报任何与PRICE相关的信息,而是20相关的信息)。

第二种定义宏函数,也是很常见的一种用法,该方法一般用于一些比较简单的函数定义,如求平方函数:

#define SQR(X) ((X)*(X))

这种定义函数的风险比较大,使用时需要谨慎,建议网上搜一下相关的坑,根据自己实际的使用需求来规避风险。同时需要注意的是,宏函数并不是真正意义的函数,它只是一个语句替换,使用时并没有所谓函数调用与返回值等操作,原理和第一种用法相同。

第三种用法是我个人认为在编程中比较有意思的点,先给出一个大家很常见的例子:

//file name: a.h
#ifndef _MY_HEADER_FILE_H_
#define _MY_HEADER_FILE_H_

class Student
{
   public:
   //...
   private:
   //...
}

#endif

上述这种处理方式在C++项目中很常见,是一种避免头文件重复引用的方式,假设a.cpp文件包含了上述头文件,那么在编译时,由于没有预定义 _MY_HEADER_FILE_H_,预处理时就会定义出该宏,同时引入该文件中的类定义内容,后续如果其他文件再次重复包含了该头文件,则由于已经定义了该宏,头文件内容就不会被再次包含一遍;

与该应用类似的一种用法是导出类的预处理:

#ifdef MY_FUNC_EXPORT
#define EXPORT_OWNER __declspec(dllexport)
#else
#define EXPORT_OWNER __declspec(dllimport)
#endif

class EXPORT_OWNER MyStudent
{
   public:
   //...
   private:
//....
}

上述例子中,通过宏定义对 EXPORT_OWNER 进行了条件处理,不同条件下,该类分别为导出类导入类,对于项目自身,在编译时一般生成静态库或动态库文件,类需要编译为导出类,那么只需要预先定义一个 MY_FUNC_EXPORT 宏即可。在调用该类的文件中,包含该头文件时,需要其为导入类,则不定义 MY_FUNC_EXPORT 就行了。

其他还有很多灵活的用法。

注:

对宏定义而言,由于其在预处理阶段会被执行替换操作,因此它一般没法使用命名空间来进行调用。如:

namespace JIUJIU
{
   #define NUM1 1000
   #define NUM2 2000
}

那么在代码中如果首先加入“using namespace JIUJIU”,然后使用宏定义NUM1和NUM2都是没有问题的,但是直接使用JIUJIU::NUM1或者JIUJIU::NUM2是会报错的,因为两种方法的NUM1和NUM2都会被替换成数字,但是第二种方法引用时相当于是JIUJIU::1000和JIUJIU::2000,而在JIUJIU这个命名空间内,并没有定义1000和2000,所以会报错。

参考:

https://blog.csdn.net/shaonian_wuya/article/details/9883599

https://blog.csdn.net/qq_30815237/article/details/89013148

 

上一篇:Hadoop3.1.4伪分布配置


下一篇:还有人不知道怎么涂口红?