避免同一个文件被include多次的方法

C/C++中有两种方式避免同一个文件被include多次

一种是#ifndef方式,一种是#pragma once方式:

方式一:

#ifndef __SOMEFILE_H__

#define __SOMEFILE_H__

... ... // 声明、定义语句

#endif

方式二:

#pragma once

... ... // 声明、定义语句

#ifndef的方式受C/C++语言标准支持。它不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。

当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,编译器却硬说找不到声明的状况——这种情况有时非常让人抓狂。

由于编译器每次都需要打开头文件才能判定是否有重复定义,在包含一个文件的时候,只有打开这个文件,根据文件的保护宏是否已经被定义来判断此文件是否已经被包含过,所以效率相对较低。

因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。

#pragma once一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。你无法对一个头文件中的一段代码作pragma
once声明,而只能针对文件。

效率更高:因为不需要去打开包含的文件,就可以判断这个文件有没有被包含,当然这个工作是系统帮我们完成的。

其好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。大型项目的编译速度也因此提高了一些。

对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

#pragma once方式产生于#ifndef之后,目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。一般而言,当程序员听到这样的话,都会选择#ifndef方式,为了努力使得自己的代码“存活”时间更久,通常宁愿降低一些编译性能。

还有一种用法是把两者放在一起的:

#pragma once

#ifndef __SOMEFILE_H__

#define __SOMEFILE_H__

... ... // 声明、定义语句

#endif

看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,也无法避免不支持#pragma once的编译器报错,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。

在#include的时候,程序员也可以自己判断所要包含的文件的保护宏是否已经被定义,来决定是否要包含这个文件。类似下面的代码:

[cpp] view
plain
copy

  1. #ifndef FILE_H_
  2. #include "file.h"
  3. #endif

这样作可以得到较高的效率,而且保证可移植性。但是文件之间的依赖性较高,如果一个文件的保护宏改变的话,所有使用如上形式包含这个文件的文件都要修改,有悖于模块化的思想。

附:如何保证使用的标识符在其他地方没有使用过?

/* things.h */

#ifndef THINGS_H_

#define THINGS_H_

...

#endif

通常编译器提供商采用如下方法:用文件名作为标识符,并在文件名中使用大写字母。用下划线代替文件名中的句点符号,用下划线(可能两条下划线)作前缀和后缀。

所以,为了避免跟编译器提供的头文件相冲突,采取的方法是把编译器标识符去掉前缀,也就是前缀不用下划线,其他按照编译器的方法。上面的示例就是采用的这种方法。

from:http://blog.csdn.net/pipisorry/article/details/38512433

ref:http://blog.csdn.net/holybin/article/details/28397157

http://zhangzhiyin1982.blog.163.com/blog/static/2899121720076259553175/

http://blog.csdn.net/hkx1n/article/details/4313303

避免同一个文件被include多次的方法

时间: 2024-11-02 16:35:20

避免同一个文件被include多次的方法的相关文章

Google Drive 和 Dropbox 同步同一个文件夹目录

 Dropbox 也是非常棒的同步工具,例如先进的增量上传或者更开放的 API 等.可是为什么不曾想过把 Google Drive 和 Dropbox 同时使用呢,我是说,让这两者同时云同步同一个文件夹目录?这样我既可以使用前者强大的协作编辑功能,也能使用后者更丰富的 API 接口.可我只在网上看到一个同步另一个子目录的形式,这很不好.于是,在我自己的一番尝试后,我成功地达到了目的,下面是我的方法. 指引 / 跳至[收缩] 1 退出并清理内容 2 下载并安装 Dropbox 3 下载并安装 Go

模板类的定义和实现可以不在同一个文件中

写c++程序时我们经常会把函数的定义写在xxx.h中,把函数的实现写在xxx.cpp, 但是当我们写带模版的函数和类时,这样写 就会出现问题,如下: stack.h //stack.h #ifndef STACK_HPP #define STACK_HPP #include <vector> #include <stdexcept> template<typename T, typename TContainer = std::vector<T>> clas

PHP包含文件函数include、include_once、require、require_once区别总结

一.使用语法和简介 1.include() 语法:include(/path/to/filename)include()语句将在其被调用的位置处包含一个文件.包含一个文件与在该语句所在位置复制制定文件的数据具有相同内容的效果.使用include()时可以忽略括号. 可以根据条件来执行include()语句.在条件语句中使用include()有个怪现象,它必须包围在语句块大括号中,或者用其他语句包围符括起来. 2.include_once() 语法:include_once(filename) i

文件包含include和require区别

文件加载原理: 1.文件加载(include或require)的时候,系统会自动的将包含文件中的代码嵌入到当前文件中 2.加载位置:在哪加载?对应的文件中的代码嵌入的位置就是对应的include位置 ,当前位置(跟html img 图片的路径差不多). <?php include './wen/index.php'; echo $str; //当前代码中没有$str include 引用后可以使用 ?> <?php // mt_rand(int $min,int $max) 产生随机数函

python多线程读取同一个文件

多线程读取同一个文件,要求不能重复,不能遗漏. 最开始尝试了一种方法(后来实践证明是无效的) 主线程分配给每个读线程需要读取文件中哪些行, 比如线程1读取1-10行,线程2读取11-30行. 然后每个线程通过readline()来读取,读到的行如果不属于本线程的范围,则continue跳过. 实践证明,这若干个线程并没有按照我们期望来读. 我的猜想是,通过open来打开一个文件,多个线程返回的是同一个句柄, 或者一个文件的文件指针只有一个. 经过网上搜索和实践,总结出有以下方法支持多线程读取同一

php学习笔记6--php中的文件包含 include,require,include_once,require_once

php中的文件包含 include,require,include_once,require_once 文件包含:是指将一个文件的内容包含进另外一个文件,有利于代码的复用等.php中文件包含指令有4个,分别为:include,include_once,require,require_once其中:include和require:使用一次便包含一次文件;而include_once和require_once则是:不管在一个脚本中包含另外一个脚本多少次,都只加载一次,不会重复,这样可以避免因一个文件的

包含文件函数include与require的区别

include或include_once一般用于动态包含,所谓动态包含就是根据不同条件包含不同文件 require或require_once一般用于静态包含,比如包含一个html文件的头部或者尾部 如:require_once footer.inc.php include和require可以包含多次,include_once和require_once只包含一次 包含文件函数include与require的区别,布布扣,bubuko.com

转: Eclipse 分屏显示同一个文件

Eclipse 分屏显示同一个文件 场景 : 某个类很大,可能有数千行.当你想要将类开头部分与中间或者靠后的部分进行对比时,请follow如下步骤: Window -> Editor -> Toggle Split Editor (Ctrl + _) 或者 Toggle Split Editor (Ctrl + {) 另一种方法 : 直接按快捷键 Ctrl + Shift + [  或者 Ctrl + Shift + - Notice : 上下分屏 : Ctrl + Shift + - 左右分

VS 2010不显示头文件源文件和所有以前分类的文件夹,*.h 和*.cpp都显示在同一个文件

打开VS后不显示头文件源文件和所有以前分类的文件夹,*.h 和*.cpp都显示在同一个文件 点击右图红色指示显示所有文件夹按钮,就能恢复.