一:在什么阶段处理 ?

预处理 预处理 预处理

首先注意这四个头文件保护符是在预处理阶段由系统默认的预处理器(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 避免重复引用的更多相关文章

  1. #ifndef #define #endif 防止头文件被重复引用

    想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...

  2. ifndef/define/endif 和 #ifdef 、#if 作用和用法

    为了能简单的看看某些linux内核源码,复习了一下c语音,今天汇总了一下关于宏定义的相关内容: 一.ifndef/define/endif用法: .h文件,如下: #ifndef XX_H #defi ...

  3. C++头文件为什么要加#ifndef #define #endif

    #ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...

  4. #ifndef#define#endif的用法

    在网上看到了感觉作者总结得很好,作者辛苦了! #ifndef#define#endif的用法 文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都 ...

  5. #ifndef#define#endif的用法(整理)

    [转] #ifndef#define#endif的用法(整理)    原作者:icwk  文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都in ...

  6. 头文件里面的ifndef /define/endif的作用

    c,c++里面,头文件里面的ifndef /define/endif的作用 今天和宿舍同学讨论一个小程序,发现有点地方不大懂······ 是关于头文件里面的一些地方: 例如:要编写头文件test.h ...

  7. 转 #ifndef/#define/#endif使用详解

    想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...

  8. 头文件为什么要加#ifndef #define #endif

    #ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...

  9. 头文件中的#ifndef/#define/#endif 的作用

    在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...

随机推荐

  1. CSS写一个缺角的div和菱形

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. ☕【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了!

    JPA的介绍分析 Java持久化API (JPA) 显著简化了Java Bean的持久性并提供了一个对象关系映射方法,该方法使您可以采用声明方式定义如何通过一种标准的可移植方式,将Java 对象映射到 ...

  3. Web爬虫|入门实战之糗事百科(附源码)

    coding by real mind writing by genuine heart 解析 任务背景:https://www.qiushibaike.com/hot/   窥探网页细节:观察每一页 ...

  4. python从网络摄像头获取rstp视频流并截取图片保存

    import cv2 def get_img_from_camera_net(folder_path):     cap = cv2.VideoCapture("rtsp://admin:a ...

  5. 51nod1229-序列求和V2【数学,拉格朗日插值】

    正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1229 题目大意 给出\(n,k,r\)求 \[\sum_{i=1}^ni ...

  6. Hibernate 的 <= 出现问题

    问题模拟 select new map( e.name as name , e.salary as salary) from Emplpyee e where e.salary <= :sala ...

  7. 实验3:OpenFlow协议分析实践

    作业链接:实验3:OpenFlow协议分析实践 一.实验目的 能够运用 wireshark 对 OpenFlow 协议数据交互过程进行抓包: 能够借助包解析工具,分析与解释 OpenFlow协议的数据 ...

  8. WinForm事件与消息

    WinForm事件与消息 消息概述以及在C#下的封装 Windows下应用程序的执行是通过消息驱动的.所有的外部事件,如键盘输入.鼠标移动.按动鼠标都由OS系统转换成相应的"消息" ...

  9. 微信小程序应用安全分析及设计

    针对微信关于小程序安全设计的分析 针对微信小程序开发配置及部分配置机制分析微信小程序安全设计: AppSecret 管理员生成AppSecret,在与微信后台交互过程中部分接口使用,如 auth.co ...

  10. Android应用开发特色

    目录 Android应用开发特色 四大组件 Activity Service Broadcastreceiver Contentprovider 丰富的系统控件 Sqlite数据库 强大的多媒体 An ...