当前位置 博文首页 > 小龙狗的博客:C++中的ifndef/define/endif的使用

    小龙狗的博客:C++中的ifndef/define/endif的使用

    作者:[db:作者] 时间:2021-07-10 09:38

    目录

    问题引入

    使用方法

    另一种方法

    参考


    问题引入

    假设你的工程里面有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

    cs
    下一篇:没有了