C 標頭檔案重複包含的解決方案

2021-06-05 10:53:11 字數 2370 閱讀 8776

一、#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 here

4:#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則由編譯器提供保證:同乙個檔案不會被包含多次。注意這裡所說的「同乙個檔案」是指物理上的乙個檔案,而不是指內容相同的兩個檔案。帶來的好處是,你不必再費勁想個巨集名了,當然也就不會出現巨集名碰撞引發的奇怪問題。對應的缺點就是如果某個標頭檔案有多份拷貝,本方法不能保證他們不被重複包含。當然,相比巨集名碰撞引發的「找不到宣告」的問題,重複包含更容易被發現並修正。

方式一由語言支援所以移植性好,方式二 可以避免名字衝突

標頭檔案重複包含

如果某個標頭檔案被多次包含,則在vc編譯器中編譯,會丟擲 重複定義 錯誤。為了避免同乙個檔案被重複包含多次,c 提出了2種解決方案。1 ifndef some file h define some file h endif 在檔案末端 2 pragma one ifndef define endif...

標頭檔案重複包含

如果某個標頭檔案被多次包含,則在vc編譯器中編譯,會丟擲 重複定義 錯誤。為了避免同乙個檔案被重複包含多次,c 提出了2種解決方案。1 ifndef some file h define some file h endif 在檔案末端 2 pragma one ifndef define endif...

C 防止標頭檔案重複包含

1.預編譯階段,把所有 include h 用.h的內容來替換了,所以之後就沒有.h了所有.h的內容都已經包含進了需要它們的.cpp中 2.生成最後的exe檔案是由編譯 鏈結兩步完成的,編譯是源 生成obj二進位制目標檔案的過程,注意乙個源 檔案生成乙個obj檔案,例如a.cpp中可以有乙個void...