一、#pragma once(比較常用) 這是一個比較常用的指令,只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次 #pragma once用來防止某個頭文件被多次include,#ifndef,#define,#endif用來防止某個宏被多次定義。 #pragma once是編譯相關,就是說這個編譯系統上能用,但在其他編譯系統不一定可以,也就是說移植性差,不過現在基本上已經是每個編譯器都有這個定義了。 #ifndef,#define,#endif這個是C++語言相關,這是C++語言中的宏定義,通過宏定義避免文件多次編譯。所以在所有支持C++語言的編譯器上都是有效的,如果寫的程序要跨平台,最好使用這種方式 二、#ifndef~#define~#endif 1: #ifndef SALESITEM_H2: #define SALESITEM_H3: // Definition of Sales_itemclass and related functions goes here4: #endif 頭文件應該含有保護符,即使這些頭文件不會被其他頭文件包含。編寫頭文件保護符並不困難,而且如果頭文件被包含多次,它可以避免難以理解的編譯錯誤。 在編寫頭文件之前,我們需要引入一些額外的預處理器設施。預處理器允許我們自定義變量。 預處理器變量 的名字在程序中必須是唯一的。任何與預處理器變量相匹配的名字的使用都關聯到該預處理器變量。 為了避免名字沖突,預處理器變量經常用全大寫字母表示。 預處理器變量有兩種狀態:已定義或未定義。定義預處理器變量和檢測其狀態所用的預處理器指示不同。#define指示接受一個名字並定義該名字為預處理器變量。#ifndef 指示檢測指定的預處理器變量是否未定義。如果預處理器變量未定義,那麼跟在其後的所有指示都被處理,直到出現 #endif。 可以使用這些設施來預防多次包含同一頭文件: #ifndef SALESITEM_H #define SALESITEM_H // Definition of Sales_itemclass and related functions goes here #endif 條件指示 #ifndef SALESITEM_H 測試 SALESITEM_H 預處理器變量是否未定義。如果 SALESITEM_H 未定義,那麼 #ifndef 測試成功,跟在#ifndef 後面的所有行都被執行,直到發現 #endif。相反,如果 SALESITEM_H 已定義,那麼 #ifndef 指示測試為假,該指示和 #endif 指示間的代碼都被忽略。 為了保證頭文件在給定的源文件中只處理過一次,我們首先檢測 #ifndef。第一次處理頭文件時,測試會成功,因為 SALESITEM_H 還未定義。下一條語句定義了 SALESITEM_H。那樣的話,如果我們編譯的文件恰好又一次包含了該頭文件。#ifndef 指示會發現 SALESITEM_H 已經定義,並且忽略該頭文件的剩余部分。 頭文件應該含有保護符,即使這些頭文件不會被其他頭文件包含。編寫頭文件保護符並不困難,而且如果頭文件被包含多次,它可以避免難以理解的編譯錯誤。 當沒有兩個頭文件定義和使用同名的預處理器常量時,這個策略相當有效。我們可以為定義在頭文件裡的實體(如類)命名預處理器變量來避免預處理器變量重名的問題。一個程序只能含有一個名為 Sales_item 的類。通過使用類名來組成頭文件和預處理器變量的名字,可以使得很可能只有一個文件將會使用該預處理器變量 三、比較 #pragma once與 #ifndef的區別 為了避免同一個文件被include多次 1 #ifndef方式 2 #pragma once方式 在能夠支持這兩種方式的編譯器上,二者並沒有太大的區別,但是兩者仍然還是有一些細微的區別。 方式一: #ifndef __SOMEFILE_H__ #define __SOMEFILE_H__ ... ... // 一些聲明語句 #endif 方式二: #pragma once ... ... // 一些聲明語句 #ifndef的方式依賴於宏名字不能沖突,這不光可以保證同一個文件不會被包含多次,也能保證內容完全相同的兩個文件不會被不小心同時包含。當然,缺點就是如果不同頭文件的宏名不小心“撞車”,可能就會導致頭文件明明存在,編譯器卻硬說找不到聲明的狀況 #pragma once則由編譯器提供保證:同一個文件不會被包含多次。注意這裡所說的“同一個文件”是指物理上的一個文件,而不是指內容相同的兩個文件。帶來的好處是,你不必再費勁想個宏名了,當然也就不會出現宏名碰撞引發的奇怪問題。對應的缺點就是如果某個頭文件有多份拷貝,本方法不能保證他們不被重復包含。當然,相比宏名碰撞引發的“找不到聲明”的問題,重復包含更容易被發現並修正。 方式一由語言支持所以移植性好,方式二可以避免名字沖突