2011-05-01 243 views
0

好吧,直到現在,我認爲在頭文件中定義的函數被視爲內聯函數,就像模板的東西,一次定義一樣。爲什麼我明確地必須在這裏聲明函數?

我也使用包含守衛,但我仍然有多個定義的對象的鏈接器錯誤,我知道這是因爲所有這些不同的單位重複的東西鏈接器試圖挑選哪個項目是正確的。

我也知道,內聯僅僅是一個建議,甚至可能沒有得到由編譯器使用等

然而,我必須明確地定義那個小頭所有這些小功能,唯一的工具,我寫。

即使函數很大,我也不得不聲明它們是內聯的,編譯器仍然可能忽略這個提示。但是我不得不這樣定義它們。

實施例:

#ifndef texture_math_h__ 
#define texture_math_h__ 

float TexcoordToPixel(float coord, float dimension) 
{ 
    return coord * dimension; 
} 

float PixelToTexcoord(float pixel, float dimension) 
{ 
    return pixel/dimension; 
} 

float RecalcTexcoord(float coord,float oldDimension, float newDimension) 
{ 
    return PixelToTexcoord(TexcoordToPixel(coord,oldDimension),newDimension); 
} 
#endif // texture_math_h__ 

錯誤是,在xxx.obj已經定義,對於每個包括所述文件

當我聲明所有那些行內的單位布拉布拉,它正確地鏈接。

這是什麼原因?這不是一個巨大的問題,而且,優化可能是內聯在cpp中找到的東西,對吧?

我只是好奇爲什麼在這裏,希望它不是太多的重複,並感謝您的時間。

+1

您能否提供一個代碼示例? – 2011-05-01 09:48:54

+1

http://www.parashift.com/c++-faq-lite/inline-functions.html – Anycorn 2011-05-01 09:51:57

+0

@Anycorn:那麼'auto'內聯shtick只適用於類成員函數,而不是常規函數呢? – Erius 2011-05-01 09:56:08

回答

4

包含警衛只防範代碼被包含兩次相同翻譯單元。因此,如果您有多個包含相同標題的文件,則代碼將包含多次。在頭文件中定義的函數默認不是內聯的,所以這會給你鏈接器錯誤 - 你需要用inline關鍵字定義這些函數,除非它們是類的成員函數。

另外,請注意,包含雙下劃線的名稱是爲C++實現而保留的 - 您不能在自己的代碼中創建這樣的名稱。

+0

好的,謝謝你的幫助。我認爲這暗示着內聯的東西超越了類。乾杯!編輯:那些ifdef名字來自視覺輔助x的'包圍守衛'功能。我不會用這個慣例來表達我自己的名字,是的。關於雙下劃線的 – Erius 2011-05-01 10:02:36

+0

:這不僅適用於標識符的開頭嗎? – MFH 2011-05-01 10:03:48

+0

@MFH不,這是單個下劃線,後跟一個大寫字母,如果在全局範圍內使用,則後跟任何內容。 – 2011-05-01 10:05:20

1

成員函數有潛力內聯 - 你不能強制內聯! - 如果(a)它們是在類中定義的,或者(b)在定義中使用了inline子句。請注意,如果您使用的內聯子句不應該定義頭中的函數 - 唯一的例外是模板,因爲它們是「特殊的」。
正如你剛纔更新的問題:
這個頭的每個用戶將有一個函數定義 - >多個定義。你需要單獨定義和聲明!

+0

我明白了,所以我在這裏實際上運動風格很差?仍然綠色和所有。 – Erius 2011-05-01 09:59:34

+0

爲什麼你不應該在頭文件中定義函數?這是inline關鍵字的主要目的! – 2011-05-01 10:01:43

+0

還有那個。我一直認爲,如果在'.cpp'中定義內聯函數而不是'.h',那麼在大多數情況下,編譯器將不能**內聯你的函數(導致它無法訪問它的實現)。 – beduin 2011-05-01 10:05:12

1

這一切都是關於的一個定義規則。這表明您只能在鏈接到該程序的所有翻譯單元的C++程序中爲每個非內聯函數(以及各種其他類型的實體)定義一個定義。

標記功能inline使通常的的例外情況成爲一個定義規則。它聲明(換言之)如果所有定義都匹配,並且在使用內聯函數的每個翻譯中都提供了定義,則每個翻譯單元可以有一個內聯函數的定義。

通過包含多次包含定義的頭文件,包含防護將防止您意外地爲每個翻譯單元提供多個定義。

要滿足對於非內聯函數的一個定義規則,您仍然必須確保只有一個包含函數定義的翻譯單元。通常的做法是隻通過聲明頭文件中的函數並使用包含定義的單個源文件。

相關問題