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 

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的区别》

你可能感兴趣的:(022 C++ 头文件保护)