2009-10-31 12 views
321

byłem widząc kod jak to zwykle w początku plików nagłówkowych:Dlaczego stosowane są pliki nagłówkowe #ifndef i #define w plikach nagłówkowych C++?

#ifndef HEADERFILE_H 
#define HEADERFILE_H 

A na końcu pliku jest

#endif 

Jaki jest cel tego?

+22

+1 - Ja też miałem tę samą wątpliwość, i dostałem o wiele więcej dobrej odpowiedzi tutaj, może być przydatne dla przyszłych odwiedzających: http://stackoverflow.com/q/3246803/1134940 –

+5

Chcę dodać do tego, że można również użyj ** # pragma once **, to wszystko, co musisz zrobić i służy temu samemu celowi co ifndef. Dla porównania dwóch, zobacz: http://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards – Dimension

+2

Najlepiej wspomnieć o tym, czym jest '# pragma': aktywuje funkcję specyficzną dla kompilatora. Chociaż '#pragma once' jest * bardzo * szeroko wspierany, jest niestandardowy. – Potatoswatter

Odpowiedz

369

Nazywa się #include guards.

Po dołączeniu nagłówka sprawdza, czy zdefiniowana jest unikalna wartość (w tym przypadku HEADERFILE_H). Jeśli nie jest zdefiniowany, definiuje go i przechodzi do reszty strony.

Po ponownym dołączeniu kodu pierwszy ifndef kończy się niepowodzeniem, co powoduje powstanie pustego pliku.

To zapobiega podwójnej deklaracji jakichkolwiek identyfikatorów, takich jak typy, wyliczenia i zmienne statyczne.

+3

Mmm interresting. Kiedyś zaprzestałem VC++, ponieważ dało mi to błędy dotyczące podwójnych definicji.Nevermind Jestem koderem Objective-C teraz =) –

+0

Koning Baard XIV: VC ma nawet '#pragma once' co robi to samo :-) – Joey

+63

Zapobiega także rekurencyjnym inkluzjom ... Wyobraź sobie" alice.h "zawiera" bob.h "i" bob.h "zawiera" alice.h "i nie zawierają one strażników ... –

21
#ifndef <token> 
/* code */ 
#else 
/* code to include if the token is defined */ 
#endif 

#ifndef sprawdza, czy dany znak został #defined wcześniej w pliku lub w dołączonym pliku; jeśli nie, zawiera kod między nim a zamykającym #else lub, jeśli nie ma #else jest obecny, oświadczenie #endif. #ifndef jest często używany do tworzenia plików nagłówkowych idempotent przez zdefiniowanie tokena po dołączeniu pliku i sprawdzenie, czy token nie został ustawiony na górze tego pliku.

#ifndef _INCL_GUARD 
#define _INCL_GUARD 
#endif 
+3

Identyfikatory zaczynające się od podkreślnika są zarezerwowane; nie powinieneś sam ich definiować. Użyj czegoś takiego jak '#ifndef H_HEADER_NAME'. –

+5

Wiem, że jest to stary komentarz, ale w rzeczywistości ograniczenie podkreślenia dotyczy tylko "zewnętrznych identyfikatorów" - identyfikatorów, które mogą znaleźć się w tablicy symboli obiektu skompilowanego, tj. Zmiennych globalnych i nazw funkcji. Nie dotyczy to nazw makr. – Stu

+1

Czy komentarz Stu jest prawdziwy? Właśnie czytam https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier i teraz nie jestem tego taki pewien. – Will

2

To zapobiega wielokrotnemu włączaniu tego samego pliku nagłówkowego wielokrotnie.

#ifndef __COMMON_H__ 
#define __COMMON_H__ 
//header file content 
#endif 

Załóżmy, że ten plik nagłówkowy został zawarty w wielu plikach. Tak więc po raz pierwszy __COMMON_H__ nie jest zdefiniowany, zostanie zdefiniowany i dołączony plik nagłówkowy.

Następnym razem, gdy zdefiniowane jest __COMMON_H__, więc nie będzie ono dołączane ponownie.

Powiązane problemy