#ifndef #define #endif #ifdef 避免重复引用
一:在什么阶段处理 ?
预处理 预处理 预处理
首先注意这四个头文件保护符
是在预处理阶段由系统默认的预处理器
(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.h
和B.h
如下所示:
之后再次预处理下看看:
发现class A
只有一份了吧!并且编译正常通过。
四:总结
其实这几个头文件保护符
应该作为我们的一种编程习惯,而不是在发生冲突的时候才使用。这样保证了我们工程的健壮。至于它们别的作用,条件编译等等,也是对这几个符号的属性不同的利用场景罢了,我就不赘述了。
#ifndef #define #endif #ifdef 避免重复引用的更多相关文章
- #ifndef #define #endif 防止头文件被重复引用
想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...
- ifndef/define/endif 和 #ifdef 、#if 作用和用法
为了能简单的看看某些linux内核源码,复习了一下c语音,今天汇总了一下关于宏定义的相关内容: 一.ifndef/define/endif用法: .h文件,如下: #ifndef XX_H #defi ...
- C++头文件为什么要加#ifndef #define #endif
#ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...
- #ifndef#define#endif的用法
在网上看到了感觉作者总结得很好,作者辛苦了! #ifndef#define#endif的用法 文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都 ...
- #ifndef#define#endif的用法(整理)
[转] #ifndef#define#endif的用法(整理) 原作者:icwk 文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都in ...
- 头文件里面的ifndef /define/endif的作用
c,c++里面,头文件里面的ifndef /define/endif的作用 今天和宿舍同学讨论一个小程序,发现有点地方不大懂······ 是关于头文件里面的一些地方: 例如:要编写头文件test.h ...
- 转 #ifndef/#define/#endif使用详解
想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...
- 头文件为什么要加#ifndef #define #endif
#ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...
- 头文件中的#ifndef/#define/#endif 的作用
在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...
随机推荐
- P1088 [NOIP2004 普及组] 火星人
题目描述 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学 ...
- 再谈OAuth授权
工作场景流程 大家都知道OAuth是用于第三方授权的,当你用其他的APP想访问微信账号的昵称.粉丝.联系人等信息,这里就需要微信进行授权,此时在APP的网页端是可以发现有微信登录的,点开会出现弹框,在 ...
- redis 设置密码 laravel框架配置redis
* 参考资料 redis文档 http://www.redis.cn/documentation.html, http://redisdoc.com/index.html r ...
- 鸿蒙内核源码分析(线程概念篇) | 是谁在不停的折腾CPU? | 百篇博客分析OpenHarmony源码 | v21.06
百篇博客系列篇.本篇为: v21.xx 鸿蒙内核源码分析(线程概念篇) | 是谁在不断的折腾CPU | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...
- P7518-[省选联考2021A/B卷]宝石【主席树,二分】
正题 题目链接:https://www.luogu.com.cn/problem/P7518 题目大意 给出\(n\)个点的一棵树,每个点上有不大于\(m\)的数字. 然后给出一个长度为\(c\)的各 ...
- Linux Bash命令杂记(cut sort uniq wc tee)
Linux Bash命令杂记(cut sort uniq wc tee) 数据流重定向 标准输入(stdin):代码为0,使用<或<<: 标准输出(stdout):代码为1,使用&g ...
- 构建idea父工程
构建idea父工程 首先通过idea新建一个Maven项目: 选择本地Maven版本: 工程名称: 选择字符编码:utf-8 file -> Settings -> Editor -> ...
- Frida高级逆向-Hook Native(Java So)
Frida Hook Native Frida Hook Java Jni demo: function hook_java() { Java.perform(function () { const ...
- Mybatis 一级缓存 (20)
Mybatis中的一级缓存和二级缓存(本博文只是针对一级缓存说明) 概述 ORM框架一般都会有缓存机制,做为其中一员的Mybatis也存在缓存.功能是用以提升查询的效率和服务给数据库带来压力.同样的M ...
- Redis使用过程中有哪些注意事项?看看BAT这类的公司是正确使用Redis的!!
Redis使用过程中要注意的事项 Redis使用起来很简单,但是在实际应用过程中,一定会碰到一些比较麻烦的问题,常见的问题有 redis和数据库数据的一致性 缓存雪崩 缓存穿透 热点数据发现 下面逐一 ...