C++中的ifndef/define/endif的使用

版权声明:xueliangwang https://blog.csdn.net/ShyLoneGirl/article/details/82969372

目录

问题引入

使用方法

另一种方法

参考


问题引入

假设你的工程里面有4个文件,分别是a.cpp,b.h,c.h,d.h。

a.cpp的头部是:

#include "b.h "

#include "c.h "

b.h和c.h的头部都是:

#include "d.h "

而d.h里面有class D的定义。这样一来,编译器编译a.cpp的时候,先根据#include "b.h "去编译b.h这个问题,再根据b.h里面的#include "d.h ",去编译d.h的这个文件,这样就把d.h里面的class D编译了;然后再根据a.cpp的第二句#include "c.h ",去编译c.h,最终还是会找到的d.h里面的class D,但是class D之前已经编译过了,所以就会报重定义错误。

加上ifndef/define/endif的主要目的是防止头文件的重复包含和编译,这样就可以防止这种重定义错误。

使用方法

#ifndef __TEST_H__
#define __TEST_H__
    // 声明、定义语句
#endif

标识名称是可以是自由命名,但习惯上的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线。

另一种方法

除ifndef/define/endif之外,还可以用下面代码实现。

#pragma once
    // 声明、定义语句 

两者的区别在于#ifndef的方式受C/C++语言标准支持。它不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,编译器却硬说找不到声明的状况。

#pragma once一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。其好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。大型项目的编译速度也因此提高了一些。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

#pragma once方式产生于#ifndef之后,因此很多人可能甚至没有听说过。由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。但目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。

参考

https://blog.csdn.net/qq_22122811/article/details/52578074

https://blog.csdn.net/lzm18064126848/article/details/50786271

猜你喜欢

转载自blog.csdn.net/ShyLoneGirl/article/details/82969372
今日推荐