一:在什么阶段处理 ?

预处理 预处理 预处理

首先注意这四个头文件保护符是在预处理阶段由系统默认的预处理器(Linux操作系统上默认是cpp)来处理的。它们的含义如下:

#define XXX    // 将XXX声明为一个预处理变量
#ifndef XXX // 当且仅当XXX没有被定义为"真"
#ifdef XXX // 当且仅当XXX被定义时为"真"
#endif // 遇到endif结束

二:怎么使用?

给个重复定义的例子如下所示:

A.h

class A {
public:
A() = default;
A(int i) {
id = i;
}
int id;
};

B.h

class A {
public:
A() = default;
A(int i) {
id = i;
} int id;
};

main.cpp

#include<iostream>
#include"A.h"
#include"B.h" int main(int argc,char *argv[])
{
A a(9);
std::cout << a.id << std::endl;
return 0;
}

编译报错如下所示:

它提示”class A”被重复定义了,既然它的处理过程是在预处理阶段,那我们可以gcc -E生成预处理之后的文件看看。

$ g++ -E main.cpp -o main.i

看看main.i的内容,发现果然class A的内容被引入了两份

在编译的时候就会报错(cc1是Linux下默认编译器):

三:怎么改?

很容易,使用头文件保护符就好了。使用套路如下所示:

#ifndef  XXX   //如果没有定义XXX
#define XXX //那就定义XXX,直到遇到endif #endif //遇到endif表示结束定义

去修改我们的A.hB.h如下所示:

之后再次预处理下看看:

发现class A只有一份了吧!并且编译正常通过。

四:总结

其实这几个头文件保护符应该作为我们的一种编程习惯,而不是在发生冲突的时候才使用。这样保证了我们工程的健壮。至于它们别的作用,条件编译等等,也是对这几个符号的属性不同的利用场景罢了,我就不赘述了。

最新文章

  1. MICAPS数据文件格式
  2. SP Flash Tool使用异常集锦
  3. history对象的一些知识点
  4. 快速幂 fast_exp
  5. linux进程用户内存空间和内核空间
  6. Oracle 10进制转36进制
  7. perl中shift 和unshift 操作
  8. Ubuntu 创建快捷方式的方法
  9. Hadoop 相关问题
  10. SQL 插入语句汇总
  11. oracle批量插入数据
  12. android该系统的应用API选择演示版本
  13. JUnit4教程-高速入口
  14. 32位汇编第一讲x86和8086的区别,以及OllyDbg调试器的使用
  15. UVA - 11374 - Airport Express(堆优化Dijkstra)
  16. mysql alter add 使用记录
  17. Stackoverflow 珠玑:C#封装重试指定次数的功能
  18. TCP、UDP和HTTP详解
  19. 架构师修练 I - 超级代码控
  20. SQL - ROW_NUMBER,Rank 添加序号列

热门文章

  1. python BeautifulSoup html解析
  2. nginx 利用return实现301跳转
  3. jmeter如何确定ramp-up时间
  4. Abp vNext 番外篇-疑难杂症丨浅谈扩展属性与多用户设计
  5. Spring Security 学习+实践
  6. SpaCy下载及安装
  7. Linux安装配置Java
  8. 洛谷 P7541 DOBRA 题解
  9. 官宣!ElasticJob 3.0.0 版本正式发布
  10. redis在微服务领域的贡献