[英]Purpose of #ifndef FILENAME…#endif in header file
我知道它可以防止多次包含頭文件。 但是假設我確保只在一個.cpp文件中包含此文件一次。 是否還有我需要這種安全防范的情況?
不,這是包含警衛的唯一目的,但使用它們應該是一個明智的選擇:這樣做需要的時間很少,可能會節省很多。
您可以保證您的代碼只包含一次,但是您能保證任何人的代碼都包含一次嗎?
此外,想象一下:
// a.h
typedef struct { int x; int y; } type1;
// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;
// main.c
#include "a.h"
#include "b.h"
不好了! 我們main.c
只包括每一次,但bh
包含ah
,所以我們得到了ah
,盡管我們盡了最大努力,兩次。
現在想象這隱藏在三層或更多層的#include
s之后,它是一個小的內部使用專用頭,它被包含兩次,這是一個問題,因為其中一個頭#undef
編了一個它定義的宏,但是第二個頭#define
它再次打破了一些代碼,需要花費幾個小時來弄清楚為什么存在相互矛盾的定義。
這是它唯一的存在理由。 即使你認為你有這個問題,這仍然是一個好主意; 它不會減慢你的代碼速度或任何東西,並且永遠不會傷害到額外的防守。
保護的目的是為了防止文件被重新列入同一.cpp文件不止一次。 它不能防止將文件包含在多個.cpp文件中。
如果您確定頭文件未包含在另一個頭文件中,則不需要保護。 但它還是很好的形式。
甚至更好的形式是使用
#pragma once
如果您的編譯器支持它。
確保您的代碼只包含一次是所謂的“標題保護”的唯一目的。
這可能很有用,好像在您的頭文件之間存在循環依賴關系,您不會陷入包含文件的無限循環中。
我能想到的另一個場景(我們做到了)是創建C ++模擬。
您在構建中明確定義了文件GUARD值,然后您可以通過-include my_mock.h作為附加編譯器選項(我們使用g ++)添加您自己的模擬實現。
my_mock.h
#define THAT_FILE_GUARD
class ThatClass
{
void connect()
{
std::cout << "mock connect" << std::endl;
}
}
使用像這樣的頭文件加速編譯過程,想象有三個源文件使用頭(減去頭部保護),這反過來意味着編譯器必須多次包括頭(解析和lexing語法) 。
有了一個標題保護,編譯器會說'哈! 我以前見過這個,並且我不會解析/ lex語法'從而加快編譯過程。
希望這會有所幫助,最好的問候,湯姆。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.