C++ 头文件保护符
头文件保护符有什么作用?
在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++ 头文件保护符的更多相关文章
- C++预处理和头文件保护符
一预处理 1.常见的预处理功能 预处理器的主要作用就是把通过预处理的内建功能对一个资源进行等价替换,最常见的预处理有:文件包含,条件编译.布局控制和宏替换4种.文件包含:#include 是一种最为常 ...
- C++编程规范之23:头文件应该自给自足
摘要: 各司其责:应该确保所编写的每个头文件都能够独自进行编译,为此需要包含其内容所依赖的所有头文件. 如果一个文件包含某个头文件时,还要包含另一个头文件才能工作,就会增加交流障碍,给头文件的用户增添 ...
- 小猪猪逆袭成博士之C++基础篇(二) 常量、处理类型、自定义头文件
小猪猪逆袭成博士之C++基础篇(二) const .auto. decltype 上一章我们介绍了一些常用的类型和常见的问题,下面再介绍一些学习的时候不是特别常用但是在实际工程中很有用的一些东西. 一 ...
- gcc编译时头文件和库文件搜索路径
特殊情况:用户自定义的头文件使用#include"mylib"时,gcc编译器会从当前目录查找头文件 一.头文件 gcc 在编译时寻找所需要的头文件 : ※搜寻会从-I开始( ...
- Makefile自动生成头文件依赖
前言 Makefile自动生成头文件依赖是很常用的功能,本文的目的是想尽量详细说明其中的原理和过程. Makefile模板 首先给出一个本人在小项目中常用的Makefile模板,支持自动生成头文件依赖 ...
- c++中,保证头文件只被编译一次,避免多重包含的方法
保证头文件只被编译一次 #pragma once这是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次. #pragma once是编译器相关的,有的编译器支 ...
- direct.h头文件(对目录操作)
chdir()改变当前目录的函数原形:int chdir(const char *path)功能:把由path指定的目录改为当前目录.path参数中可以指定驱动器号,如“a:\\ddd”, 但只是改变 ...
- CONFIG_*头文件的配置
通常在kernel或uboot中, 有很多以CONFIG_*开头的宏配置选项,并且保存在相应的头文件中,那么这些CONFIG_*是怎么生成的呢? 在uboot的顶层Makefile中,有这么一项: 此 ...
- 【C】.h头文件的重复包含问题
.h头文件存在的意义就是封装,可以方便多个.c源文件使用,但要防止.h头文件被同一个.c源文件多次包含. 例如, io.h文件 #ifndef _IO_H_ #define _IO_H_ #defin ...
随机推荐
- 《剑指offer》题解
有段时间准备找工作,囫囵吞枣地做了<剑指offer>提供的编程习题,下面是题解收集. 当初没写目录真是个坏习惯(-_-)||,自己写的东西都要到处找. 提交的源码可以在此repo中找到:h ...
- 第三十三篇 Python中关于OOP(面向对象)的常用术语
面向对象的优点 从编程进化论可知,面向对象是一种更高等级的结构化编程方式,它的好处主要有两点: 1. 通过封装明确了内外,你做为类的缔造者,你就是女娲,女娲造物的逻辑别人无需知道,女娲想让你知道,你才 ...
- Kubernetes实战 高可用集群搭建,配置,运维与应用
1-1 K8S导学 1-2 搭建K8S集群步骤和要点介绍 1-3 搭建三节点Ubuntu环境 1-4 安装容器引擎 1-5 下载Kubeadm.node组件和命令行工具 1-6 向集群中加入worke ...
- kvm-1
yum install libvirt* virt-* qemu-kvm* -y systemctl start libvirtd.service systemctl status libvirtd. ...
- 从零开始配置Jenkins(二)——常见问题及排错思路
[前言] 一年多以前就听说Jenkins了,那时知道是它可以完成自动构建,感觉蛮强大的.后来,很多人都说它很恶心.最近,公司需要搭建新的服务器,小编就负责从头开始配置并且发布部署成功每一条线每一个项目 ...
- Ubuntu如何进入命令模式
Ctrl+Alt+T 或者Ctrl+Alt+F2~F6进入命命令模式 Ctrl+Alt+F7返回桌面
- vue2.0 vue-cli项目中路由之间的参数传递
1.首先配置路由, import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new R ...
- [C/C++] C++声明和定义的区别
·变量定义:用于为变量分配存储空间,还可为变量指定初始值.程序中,变量有且仅有一个定义. ·变量声明:用于向程序表明变量的类型和名字. ·定义也是声明:当定义变量时我们声明了它的类型和名字. ·ext ...
- [Leetcode] 20. Valid Parentheses(Stack)
括号匹配问题,使用栈的特点,匹配则出栈,否则入栈,最后栈为空则全部匹配.代码如下: class Solution { public: bool isValid(string s) { stack< ...
- IE6,7,8支持css圆角
我们知道Webkit内核的浏览器支持-webkit-border-radius: 10px;属性(10px是圆角半径),可以直接解析出圆角;Firefox浏览器支持-moz-border-radius ...