头文件保护符有什么作用?

在C++中我们写头文件时经常需要#include来包含其他头文件。头文件定义的实体经常使用其他头文件的内容,有时候会出现一个头文件被多次包含进同一源文件。

例如:一个头文件中用到string类型的变量,而包含这个头文件的源文件中也用到string类型的变量,这个时候string头文件就被包含了两次:一次是通过程序本身直接包含,另一次是通过包含自写头文件而间接包含。

因此,设计头文件的时候,应该使其可以多次包含在同一源文件中,这一点是很重要的。我们必须保证多次包含同一头文件不会引起该头文件的类和对象被多次定义。使得头文件安全的通用做法是使用预处理器定义的头文件保护符。头文件保护符用于避免在已经见到头文件的情况下重新处理该头文件的内容。

头文件保护符依赖于预处理变量

为了避免命名冲突,预处理器变量经常用全大写字母表示。预处理器变量有两种状态:一定义和未定义。定义预处理器变量和检测器状态所用的预处理器指示不同。

#define指示接受一个名字并定义该名字为预处理器变量。

#ifndef指示检测指定的预处理器变量是否未定义。如果预处理器变量未定义,那么跟在其后面的所有指示都被处理,直到出现#endif。

为了保证头文件在给定的源文件中只处理一次,我们首先检测#ifndef。第一次处理头文件时,测试会成功,因为相应的预处理器还未定义。下一条语句就定义了该预处理器变量。那样的话,如果我们编译的文件敲好又一次包含了该头文件,#ifndef指示会发现该预处理器已经定义,并且忽略该头文件的剩余部分。

应用示例:

C++中,一般我们会为了防止头文件被包含多次,都会在每个头文件中写与如下类似的代码:
#ifndef A_H
#define A_H
......//头文件内容
#endif
 
头文件第一次被包含时,因为没有宏定义过“A_H”,因此经过语句

#ifndef A_H
#define A_H

并得到执行后,“A_H”就被定义了,并且头文件的内容会进入编译,直到遇见“#endif”。
 
而一旦该头文件即将被错误地包含第二次时,与语句“#ifndef A_H”不符,因为第一次你已经定义过“A_H”了,所以“#ifndef A_H”之后的语句不会进入编译了,直到遇见“#endif”。
 
若头文件被包含一次以上,编译时都会报错。C++头文件保护符的目的就是避免这类错误。

C++ 头文件保护符的更多相关文章

  1. C++预处理和头文件保护符

    一预处理 1.常见的预处理功能 预处理器的主要作用就是把通过预处理的内建功能对一个资源进行等价替换,最常见的预处理有:文件包含,条件编译.布局控制和宏替换4种.文件包含:#include 是一种最为常 ...

  2. C++编程规范之23:头文件应该自给自足

    摘要: 各司其责:应该确保所编写的每个头文件都能够独自进行编译,为此需要包含其内容所依赖的所有头文件. 如果一个文件包含某个头文件时,还要包含另一个头文件才能工作,就会增加交流障碍,给头文件的用户增添 ...

  3. 小猪猪逆袭成博士之C++基础篇(二) 常量、处理类型、自定义头文件

    小猪猪逆袭成博士之C++基础篇(二) const .auto. decltype 上一章我们介绍了一些常用的类型和常见的问题,下面再介绍一些学习的时候不是特别常用但是在实际工程中很有用的一些东西. 一 ...

  4. gcc编译时头文件和库文件搜索路径

    特殊情况:用户自定义的头文件使用#include"mylib"时,gcc编译器会从当前目录查找头文件 一.头文件 gcc 在编译时寻找所需要的头文件 :    ※搜寻会从-I开始( ...

  5. Makefile自动生成头文件依赖

    前言 Makefile自动生成头文件依赖是很常用的功能,本文的目的是想尽量详细说明其中的原理和过程. Makefile模板 首先给出一个本人在小项目中常用的Makefile模板,支持自动生成头文件依赖 ...

  6. c++中,保证头文件只被编译一次,避免多重包含的方法

    保证头文件只被编译一次 #pragma once这是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次. #pragma once是编译器相关的,有的编译器支 ...

  7. direct.h头文件(对目录操作)

    chdir()改变当前目录的函数原形:int chdir(const char *path)功能:把由path指定的目录改为当前目录.path参数中可以指定驱动器号,如“a:\\ddd”, 但只是改变 ...

  8. CONFIG_*头文件的配置

    通常在kernel或uboot中, 有很多以CONFIG_*开头的宏配置选项,并且保存在相应的头文件中,那么这些CONFIG_*是怎么生成的呢? 在uboot的顶层Makefile中,有这么一项: 此 ...

  9. 【C】.h头文件的重复包含问题

    .h头文件存在的意义就是封装,可以方便多个.c源文件使用,但要防止.h头文件被同一个.c源文件多次包含. 例如, io.h文件 #ifndef _IO_H_ #define _IO_H_ #defin ...

随机推荐

  1. Epplus下的一个将Excel转换成List的范型帮助类

    因为前一段时间公司做项目的时候,用到了Excel导入和导出,然后自己找了个插件Epplus进行操作,自己将当时的一些代码抽离出来写了一个帮助类. 因为帮助类是在Epplus基础之上写的,项目需要引用E ...

  2. fiddler抓包-简单易操作(一)

    1.下载fiddler 可以到fiddler官网去下,网址:https://www.telerik.com/download/fiddler 下载完成后,安装即可. 2.运行fiddler,进入fid ...

  3. Ubuntu 进阶命令——长期不定时更新

    有时候远程连接服务器忽然中断或者不小心关掉了终端界面,正在运行的命令或者程序就会被强制停止.这时候,我们可以借助一些命令来避免这种情况的发生. nohup 不挂断地运行命令 & 在后台运行命令 ...

  4. Cassandra 在CQL中使用函数

    CQL 3.1 最后更新 2015年10月10日 maxTimeuuid() now() dateOf() minTimeuuid() --假设表结构如下 create table user ( us ...

  5. 用JAVA写一个多线程程序,写四个线程,其中二个对一个变量加1,另外二个对一个变量减1

    package com.ljn.base; /** * @author lijinnan * @date:2013-9-12 上午9:55:32 */ public class IncDecThrea ...

  6. exec族

    在之前我们已经知道用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序.当进程调用一种exec函数时,该进程的用户空间代码和 ...

  7. Java课程设计--学生成绩管理系统

    一.团队名称: 团队成员 林艺薇 201721123032 网络1712 黄毓颖 201721123033 网络1712 唐川 201721123034 网络1712 梁才玉 201721123038 ...

  8. 【工作感悟】——xyb项目部署

    [前言] 接手xyb项目维护有一段时间了,除了熟悉业务需求和开发环境外,还没有进行新需求的开发.前几天突然接到一个任务,要去发改委给他们部署一版最新的系统.本来事情也不大,也没有很难.但是本来是大屈. ...

  9. elasticsearch 6.2.3安装ik分词

    下载 zip文件 上传到服务器 https://github.com/medcl/elasticsearch-analysis-ik/releases unzip elasticsearch-anal ...

  10. C语言100例01 PHP版(练习)

    题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 代码: for ...