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