C++头文件重复包含的解决方案

转载 2012年03月31日 09:28:34

一、#pragma once(比较常用)

这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次

#pragma once用来防止某个头文件被多次include,#ifndef,#define,#endif用来防止某个宏被多次定义。

#pragma once是编译相关,就是说这个编译系统上能用,但在其他编译系统不一定可以,也就是说移植性差,不过现在基本上已经是每个编译器都有这个定义了。

#ifndef,#define,#endif这个是C++语言相关,这是C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式

二、#ifndef~#define~#endif

1: #ifndef SALESITEM_H2: 

   #define SALESITEM_H3: 

    // Definition of Sales_itemclass and related functions goes here4: 

   #endif

头文件应该含有保护符,即使这些头文件不会被其他头文件包含。编写头文件保护符并不困难,而且如果头文件被包含多次,它可以避免难以理解的编译错误。

在编写头文件之前,我们需要引入一些额外的预处理器设施。预处理器允许我们自定义变量。

 

预处理器变量 的名字在程序中必须是唯一的。任何与预处理器变量相匹配的名字的使用都关联到该预处理器变量。

为了避免名字冲突,预处理器变量经常用全大写字母表示。

预处理器变量有两种状态:已定义或未定义。定义预处理器变量和检测其状态所用的预处理器指示不同。#define指示接受一个名字并定义该名字为预处理器变量。#ifndef 指示检测指定的预处理器变量是否未定义。如果预处理器变量未定义,那么跟在其后的所有指示都被处理,直到出现 #endif。

可以使用这些设施来预防多次包含同一头文件:

#ifndef SALESITEM_H #define SALESITEM_H // Definition of Sales_itemclass and related functions goes here #endif

 

条件指示

#ifndef SALESITEM_H

 

测试 SALESITEM_H 预处理器变量是否未定义。如果 SALESITEM_H 未定义,那么 #ifndef 测试成功,跟在#ifndef 后面的所有行都被执行,直到发现 #endif。相反,如果 SALESITEM_H 已定义,那么 #ifndef 指示测试为假,该指示和 #endif 指示间的代码都被忽略。

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

 

头文件应该含有保护符,即使这些头文件不会被其他头文件包含。编写头文件保护符并不困难,而且如果头文件被包含多次,它可以避免难以理解的编译错误。

当没有两个头文件定义和使用同名的预处理器常量时,这个策略相当有效。我们可以为定义在头文件里的实体(如类)命名预处理器变量来避免预处理器变量重名的问题。一个程序只能含有一个名为 Sales_item 的类。通过使用类名来组成头文件和预处理器变量的名字,可以使得很可能只有一个文件将会使用该预处理器变量

三、比较

 

#pragma once与 #ifndef的区别

为了避免同一个文件被include多次

1   #ifndef方式
2   #pragma once方式

在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
    方式一:

    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 一些声明语句
    #endif

    方式二:

    #pragma once
    ... ... // 一些声明语句


    #ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况

    #pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。

   方式一由语言支持所以移植性好,方式二 可以避免名字冲突

C++/C中防止头文件的重复包含的解决办法及区别

为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有...
  • XHfight
  • XHfight
  • 2016年06月01日 00:05
  • 6474

C/C++——头文件重复包含问题

条件编译是解决头文件重复包含的有效方法,在大型程序开发中,往往因类的继承产生重复定义问题,其中一个原因就是头文件的重复包含。有时候虽然重复包含一个头文件不会报错,但同样的代码多次编译也是浪费系统资源,...
  • u010757264
  • u010757264
  • 2015年11月27日 21:47
  • 1338

C/C++——头文件重复包含问题

条件编译是解决头文件重复包含的有效方法,在大型程序开发中,往往因类的继承产生重复定义问题,其中一个原因就是头文件的重复包含。有时候虽然重复包含一个头文件不会报错,但同样的代码多次编译也是浪费系统资源,...
  • u010757264
  • u010757264
  • 2015年11月27日 21:47
  • 1338

C++头文件重复包含问题分析及解决方案

一、头文件重复包含问题分析 1) 问题重现 举例说明。假设在某个C++ 头文件 或 源文件 中,包含了A.h和B.h两个头文件: #include "A.h" #include "B.h" ...
  • shufac
  • shufac
  • 2014年04月23日 00:14
  • 1082

C++/C中防止头文件的重复包含的解决办法及区别

为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有...
  • XHfight
  • XHfight
  • 2016年06月01日 00:05
  • 6474

在c/c++中如何避免头文件被多次包含?

来自:http://baike.baidu.com/view/1276747.htm   #pragma once   概述 这是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂...
  • tenfyguo
  • tenfyguo
  • 2013年04月17日 15:21
  • 5785

防止头文件重复包含的两种方法及区别

1.条件编译语句#ifndef#define#endif 相信很多人都知道第一种方法。#ifndef _TEST_H_ //——1 #define _TEST_H_ //——2 //加入...
  • lixungogogo
  • lixungogogo
  • 2016年03月27日 16:21
  • 1428

怎样防止头文件被重复包含?(两种方式)以及它的影响

一、头文件被重复包含 #include文件的一 个不利之处在于一个头文件可能会被多次包含,为了说明这种错误,考虑下面的代码: #include "x.h" #include "x.h" 显然,这里...
  • yx20130919
  • yx20130919
  • 2016年08月06日 10:38
  • 1360

如何防止头文件被重复包含或引用?

一、#pragma once ( 比较常用) 只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用。 #pragmaonce...
  • Sharp_UP
  • Sharp_UP
  • 2017年05月14日 14:14
  • 759

防止变量重复定义、头文件重复包含、嵌套包含

【转载】防止变量重复定义、头文件重复包含、嵌套包含 【转自】 http://hi.baidu.com/zengzhaonong/blog/item/8a8871062d481f7f0...
  • ljianhui
  • ljianhui
  • 2013年01月25日 12:17
  • 8061
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++头文件重复包含的解决方案
举报原因:
原因补充:

(最多只允许输入30个字)