根據編譯原理,在編譯的過程中,只是把頭檔案中的內容進行替換,若重複包含,就會使同一段**在該檔案中出現兩次或多次,引起編譯錯誤。
介紹兩種常用的方法,
其一是#ifndef:
//a為頭檔名,h代表這是乙個標頭檔案的巨集名
#ifndef a_h_
#define a_h_
//**
#endif
原理:每次編譯某一段**時要判定前面是否已經編譯過
優點是受c/c++支援,可移植性好;保證內容完全相同的兩個**片段不會被同時包含;
缺點是如果不同**片段不小心重名的話,編譯器只編譯其一;每次編譯需要判定,所以編譯大型專案時用時較長;
其二是#pragma once:
#pragma once
//**
原理:編譯檔案之前確定某一檔案只能被編譯一次
優點是不必擔心名字怎麼起,不會引起重名問題;不用判定,大型專案編譯時間大大減少
缺點是不支援跨平台;該方式是指定的同乙個檔案不被編譯兩次,如果有標頭檔案拷貝的情況,也可能會被包含兩次。
然而正是由於第一種方法支援跨平台,現在大部分人用的還是第一種。要注意,兩種方法混用更不好,使得結構紊亂。
以上兩種方法只是在寫標頭檔案時需要注意的問題,但是,只要標頭檔案這樣保證了,就不會出現標頭檔案的包含問題了嗎?當然不是。
看下面**:
//主函式
#include int main()
class a的.h檔案:
#ifndef a_h_
#define a_h_
#include "b.h"//包含類b的標頭檔案
class a
;#endif
class a的.cpp檔案:
#include "a.h"
a::a()
a::~a()
class b的.h檔案:
#ifndef b_h_
#define b_h_
#include "a.h"//包含類a的標頭檔案
class b
;#endif
class b的.cpp檔案:
#include "b.h"
b::b()
b::~b()
這樣寫看似沒毛病,但是編譯時產生錯誤,而錯誤的原因就是找不到對應的類。
這個問題是由類之間的相互呼叫引出的,由於編譯是自上而下有順序的,當類之間相互呼叫時,編譯的時候就可能編譯乙個類時找不到另乙個類,從而產生編譯錯誤。
這個問題有兩種情況,一種是在同一檔案中,另一種是在不同檔案中。而在同一檔案中的情況,新增前置宣告就行,由於不屬於標頭檔案包含問題,就不細說了。
解決該問題的關鍵就是讓編譯器編譯時能找到相應的類
解決該問題的最佳方法就是,將檔案包含都寫在.cpp檔案中,在用到某乙個類之前新增類的宣告。
將以上**修改為:
主函式不變
//主函式
#include int main()
class a的.h檔案(修改後):
#ifndef a_h_
#define a_h_
class b;//由於下面要用到類b,所以這裡宣告類b
class a
;#endif
class a的.cpp檔案(修改後):
#include "a.h"
#include "b.h"//由於類a中用到類b,所以包含b的標頭檔案,且放在.cpp檔案中
a::a()
a::~a()
class b的.h檔案(修改後):
#ifndef b_h_
#define b_h_
class a;//由於下面要用到類a,所以這裡宣告類a
class b
;#endif
class a的.cpp檔案(修改後):
b.cpp
#include "b.h"
#include "a.h"//由於類b中用到類a,所以包含a的標頭檔案,且放在.cpp檔案中
b::b()
b::~b()
實際上,就做了兩點修改,其一就是將標頭檔案包含都放到.cpp檔案中,其二就是在類前面分別加上前置宣告。這樣的處理方式可以說是一蹴而就,媽媽再也不用擔心我標頭檔案包含的時候出錯啦。。。
也許有的人會說,這是一種程式設計習慣,標頭檔案總是要包含在.cpp檔案中的。但是,有很多人不知道這個習慣。習慣是養成的,在初學程式設計時,沒人會告訴你程式設計習慣具體應該怎麼做,這需要自己去摸索。而且你應該理解為什麼會有這種習慣,這種習慣是為了避免什麼問題。
綜上所訴,標頭檔案中一般用#ifndef保證不會被重複編譯,檔案包含要放在.cpp檔案中,並且,檔案包含的時候要思考一下,能不包含就不要包含,以提公升編譯速度。
關於C 標頭檔案問題
c標頭檔案可以在c program files x86 microsoft visual studio vc98 include中找到,c 標頭檔案可以在 c program files x86 microsoft visual studio 2017 community vc tools msvc...
關於C 中的標頭檔案互相包含
在c 中一般的程式都會分成標頭檔案和cpp檔案,然後包含不同的標頭檔案可以獲得標頭檔案中的函式的引用,但是這裡就會出現乙個問題就是如果兩個檔案中同時包含了同乙個標頭檔案,例如 a.h中包含了c.h 然後在b.h中 也包含c.h 那麼就會出現上述所提到的重複包含的情況。所以在這裡可以使用乙個 ifnd...
關於c 的標頭檔案依賴
正在看google c 程式設計規範,裡面對頭檔案依賴是這麼說的 使用前置宣告 forward declarations 儘量減少.件中 include的數量。當乙個標頭檔案被包含的同時也引入了一項新的依賴 dependency 只要該標頭檔案被修改,就要重新編譯。如果你的標頭檔案包含了其他標頭檔案...