由多個(gè)文件組成的程序需要一種方法連接名字的使用和聲明,在C++中是通過(guò)頭文件實(shí)現(xiàn)的。頭文件一般包括類(lèi)的定義,extern 變量的聲明和函數(shù)的聲明。使用或定義這些實(shí)體的文件要包含適當(dāng)?shù)念^文件。 頭文件的正確使用有兩個(gè)好處:保證所有文件使用給定實(shí)體的同一聲明;當(dāng)聲明需要修改時(shí),只有頭文件需要更新。在定義頭文件時(shí)要注意頭文件中所做的聲明在邏輯上應(yīng)該是適于放在一起的,否則,編譯頭文件會(huì)花費(fèi)較長(zhǎng)時(shí)間。 使用頭文件時(shí)需要注意以下幾點(diǎn):
當(dāng)定義頭文件時(shí),記住定義和聲明的區(qū)別是很重要的。定義只可以出現(xiàn)一次,而聲明可以出現(xiàn)多次。因?yàn)轭^文件包含在多個(gè)源文件中,所以不應(yīng)該含有變量或函數(shù)的定義,否則會(huì)造成在同一個(gè)程序?qū)ν粋€(gè)變量或函數(shù)的多次定義。下列語(yǔ)句是定義,所以不應(yīng)該放在頭文件中: extern int ival = 10; double ix; 對(duì)頭文件不應(yīng)該含有定義這一規(guī)則,有三個(gè)例外。頭文件可以定義類(lèi),值在編譯時(shí)就已經(jīng)知道的const對(duì)象和inline函數(shù)。這些實(shí)體可以在多個(gè)源文件中定義,只要每個(gè)源文件中的定義是相同的。 在頭文件中定義這些實(shí)體,是因?yàn)榫幾g器需要它們的定義來(lái)產(chǎn)生代碼。例如:為了產(chǎn)生能定義或使用類(lèi)的對(duì)象的代碼,編譯器需要知道組成該類(lèi)型的數(shù)據(jù)成員,同樣還需要知道能夠在這些對(duì)象上執(zhí)行的操作。對(duì)于const對(duì)象,作以下說(shuō)明: 除非特別說(shuō)明,在全局作用域聲明的const變量默認(rèn)為是定義該對(duì)象的文件的局部變量。此變量只存在于那個(gè)文件中,不能被其他文件訪問(wèn)。通過(guò)指定const變量為extern,就可以在整個(gè)程序中訪問(wèn)const對(duì)象。例如: //在file1中定義變量ix extern const int ix = 5; //在file2中我們可以這樣使用它 extern const int ix; for (int index = 0; index != ix; ++index) {…} 通過(guò)對(duì)const變量進(jìn)行為編譯器可見(jiàn)的初始化式初始化后,const變量成為常量表達(dá)式。為了能夠讓const變量和它的初始化式在每個(gè)文件中都可見(jiàn),一般都把這樣的const變量定義在頭文件中,從而使包含該頭文件的文件都可以使用相同的常量值。無(wú)論該const變量何時(shí)使用,編譯器都可以看見(jiàn)其初始化式。在C++中任何變量都只能定義一次,定義會(huì)分配存儲(chǔ)空間,而所有對(duì)該變量的使用都關(guān)聯(lián)到同一存儲(chǔ)空間,因?yàn)閏onst對(duì)象默認(rèn)為定義它的文件的局部變量,所以把它們定義放在頭文件中是合法的。 如果const變量不是用常量表達(dá)式初始化,那么它就不應(yīng)該在頭文件中定義,相反,它應(yīng)該和其他變量一樣,該const變量應(yīng)該在一個(gè)源文件中定義并初始化,然后在頭文件中為它添加extern聲明,以使其能被多個(gè)文件共享。
#include設(shè)施是C++預(yù)處理器的一部分,它只接受一個(gè)參數(shù):頭文件名。預(yù)處理器用指定的頭文件的內(nèi)容替代每個(gè)#include.
頭文件經(jīng)常#include其他頭文件,頭文件定義的實(shí)體經(jīng)常使用其他頭文件的設(shè)施,在同一源文件中還可能多次包含同一頭文件。比如我們自己定義了一個(gè)Query.h的頭文件,該頭文件中包含了string的頭文件。同時(shí),我們?cè)诰帉?xiě)源代碼時(shí)也使用了string庫(kù),這樣string 庫(kù)就包含了兩次:一次是通過(guò)程序本身直接包含,一次是通過(guò)包含Query頭文件間接包含。 設(shè)計(jì)頭文件時(shí),應(yīng)使其可以多次包含在同一源文件中,我們必須保證多次包含同一頭文件不會(huì)引起該頭文件中定義的類(lèi)和對(duì)象被多次定義,使得頭文件安全的通用做法,是使用預(yù)處理器定義頭文件保護(hù)符來(lái)避免在已經(jīng)見(jiàn)到頭文件的情況下重新處理該頭文件的內(nèi)容。
為了避免名字沖突,預(yù)處理變量經(jīng)常用全大寫(xiě)字母表示。預(yù)處理變量有兩種狀態(tài):已定義或未定義。定義預(yù)處理器變量和檢測(cè)其狀態(tài)所用的預(yù)處理指示不同。#define指示接受一個(gè)名字并定義該名字為預(yù)處理變量。#ifndef指示檢測(cè)指定的預(yù)處理器變量是否未定義。如果預(yù)處理器變量未定義,那么跟在其后的所有指示都被處理,直到出現(xiàn)#endif??梢允褂眠@種方法來(lái)預(yù)防多次包含同一頭文件。 #ifndef QUERY_H #define QUERY_H //定義query.h中的內(nèi)容 #endif
條件指示 #ifndef QUERY_H 測(cè)試 QUERY_H預(yù)處理器變量是否未定義。如果 QUERY_H未定義,那么#ifndef測(cè)試成功,跟在#ifndef后面的所有行都被執(zhí)行,直到發(fā)現(xiàn)#endif.相反,如果QUERY_H已定義,那么#infdef指示測(cè)試為假,該指示和#endif指示之間的代碼都被忽略。通常情況下,我們用定義在頭文件中的實(shí)體(如類(lèi))來(lái)命名預(yù)處理器變量來(lái)避免預(yù)處理器變量重名的問(wèn)題。通過(guò)使用類(lèi)名來(lái)組成頭文件和預(yù)處理器變量的名字,可以使得很可能只有一個(gè)文件將會(huì)使用該預(yù)處理器變量。
#include指示接受以下兩種形式: #include<iostream> #include"query.h" 如果頭文件名括在尖括號(hào)< >里,那么認(rèn)為該頭文件是標(biāo)準(zhǔn)頭文件。編譯器會(huì)在預(yù)定義的位置集查找該頭文件,這些預(yù)定義的位置可以通過(guò)設(shè)置查找路徑環(huán)境變量或者通過(guò)命令行選項(xiàng)來(lái)修改。如果頭文件名括在一對(duì)引號(hào)里,那么認(rèn)為它是非系統(tǒng)頭文件,非系統(tǒng)頭文件的查找通常開(kāi)始于源文件所在的路徑。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注