022 C++ 头文件保护

目前头文件保护一般涉及到两个宏:

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

#pragma once 是编译器相关的,就是说这个编译系统上能用,但在其他编译系统不一定可以,其移植性差,不过现在基本上已经是主流的编译器都有这个定义了;
#ifndef ... #define ... #endif 这个是 C++ 语言相关的,这是 C++ 语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持 C++ 语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式。

#ifndef 的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况。这种问题通常发生在不同作者的类被引入的情况。因此建议大家在开发的时候类名如果是比较普遍出现的名称,则可以考虑在宏定义后面追加 UUID 值的方式,避免宏名称冲突。

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

// 混合使用两种方式
#pragma once
#ifndef FOLDER_H_89E9F1D4_69E9_43D0_BEA6_BCC6C579F3DE
#define FOLDER_H_89E9F1D4_69E9_43D0_BEA6_BCC6C579F3DE
#include <QObject>

class Folder : public QObject
{
    Q_OBJECT
public:
    explicit Folder(QObject *parent = nullptr);
// ...
};

#endif // FOLDER_H_89E9F1D4_69E9_43D0_BEA6_BCC6C579F3DE

本文参考链接《#pragma once与#ifndef ... #define ... #endif的区别

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • C中的预编译宏定义 2009-02-10 作者: infobillows 来源:网络 在将一个C源程序转换为可执行...
    白水灬煮一切阅读 1,634评论 0 5
  • 目录 一.预处理的工作方式... 3 1.1.预处理的功能... 3 1.2预处理的工作方式... 3 二.预处理...
    朱森阅读 1,394评论 0 2
  • C/C++编译系统编译程序的过程为预处理、编译、链接。预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进...
    小码兔的日常阅读 903评论 0 1
  • 此次出游本来计划是两个月,没成想计划落了空,工作还遭遇了重创,适时调整了计划,陪娃游云南,参加葫芦丝大赛。 因为计...
    暖衍阅读 262评论 2 2