C和C++區分聲明和定義。爲什麼要將整個標題內容放在守衛標記內?
您可以多次聲明一個符號,但是您只能定義它一次。通過學習這一點,我有一個主意,把聲明外面的警衛,而定義侍衛內:
// declarations
int foo(int x, int y);
int bar(int x, int y);
extern double something;
class X;
#ifndef _MY_HEADER_H_
#define _MY_HEADER_H_
#include "otherheader1.h"
#include "otherheader2.h"
// definitions of structures, classes.
class X
{
// blah blah...
};
#endif
通過這種方式,我可以有我的頭什麼爲了我想要的。可能循環依賴不會是一個問題。
那麼,如果我們可以把聲明放在外面,爲什麼要用守護標記來保護整個標題呢?
我的理由是以下幾點:
你可能經常遇到的問題時,兩個頭指對方莫名其妙。您通常會得到一個未聲明的符號錯誤,您的第一個反應是包含必要的標題。但是當你的兩個頭文件碰巧包含對方時,你會發現神祕的錯誤。
A.H:
#ifndef A_H
#define A_H
#include "b.h"
class A {B *b;}
#endif
b.h
#ifndef B_H
#define B_H
#include "a.h"
class B {A *a;}
#endif
當b.cpp您包括您在B未申報A.H得到一個錯誤,但包含在報頭中的b.h。 (這是一個跆拳道的時刻。)
是因爲那首部警衛不會窩:
#ifndef B_H
#define B_H
#ifndef A_H
#define A_H
// B_H already defined no include here.
class A {B *b;}
#endif
class B {A *a;}
#endif
如果你把聲明的防護罩外,則可以防止這種情況:
class B; // in b.h
#ifndef B_H
#define B_H
class A; // in a.h
#ifndef A_H
#define A_H
class B; // again from b.h
// B_H already defined no include here, no redefinition.
class A {B *b;}
#endif
class B {A *a;}
#endif
沒問題這裏。
更新:把標題納入警衛(抱歉是一個錯誤)。
好吧,爲什麼不呢?爲什麼要投入努力來思考可能會發生什麼,以及什麼可能不在頭衛兵?你的方式在哪裏受益? – PlasmaHH 2011-12-16 11:58:39
大部分教師和專業人員都不鼓勵在單個文件中實施課程。 – v01d 2011-12-16 12:00:19
好吧,我會使用#pragma一次。 – harold 2011-12-16 12:01:55