目前頭文件保護(hù)一般涉及到兩個宏:
#pragma once用來防止某個頭文件被多次include;
#ifndef,#define,#endif用來防止某個宏被多次定義。
#pragma once 是編譯器相關(guān)的,就是說這個編譯系統(tǒng)上能用,但在其他編譯系統(tǒng)不一定可以,其移植性差,不過現(xiàn)在基本上已經(jīng)是主流的編譯器都有這個定義了;
#ifndef ... #define ... #endif 這個是 C++ 語言相關(guān)的,這是 C++ 語言中的宏定義,通過宏定義避免文件多次編譯。所以在所有支持 C++ 語言的編譯器上都是有效的,如果寫的程序要跨平臺,最好使用這種方式。
#ifndef 的方式依賴于宏名字不能沖突,這不光可以保證同一個文件不會被包含多次,也能保證內(nèi)容完全相同的兩個文件不會被不小心同時包含。當(dāng)然,缺點就是如果不同頭文件的宏名不小心“撞車”,可能就會導(dǎo)致頭文件明明存在,編譯器卻硬說找不到聲明的狀況。這種問題通常發(fā)生在不同作者的類被引入的情況。因此建議大家在開發(fā)的時候類名如果是比較普遍出現(xiàn)的名稱,則可以考慮在宏定義后面追加 UUID 值的方式,避免宏名稱沖突。
#pragma once 則由編譯器提供保證:同一個文件不會被包含多次。注意這里所說的“同一個文件”是指物理上的一個文件,而不是指內(nèi)容相同的兩個文件。帶來的好處是,你不必再費勁想個宏名了,當(dāng)然也就不會出現(xiàn)宏名碰撞引發(fā)的奇怪問題。對應(yīng)的缺點就是如果某個頭文件有多份拷貝,本方法不能保證他們不被重復(fù)包含。當(dāng)然,相比宏名碰撞引發(fā)的“找不到聲明”的問題,重復(fù)包含更容易被發(fā)現(xiàn)并修正。
// 混合使用兩種方式
#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