2013-09-28 33 views
2

爲什麼在頭文件中定義類的函數是一種糟糕的做法?C++中頭文件中的內聯函數

可以說我有一個頭文件,我定義的類定義本身喜歡之類的功能,

headerfile.hpp

#ifndef _HEADER_FILE_ 
#define _HEADER_FILE_ 

class node{ 
int i; 

public: 
int nextn(){ 
...... 
return i; 
} 
} 

#endif //_HEADER_FILE_ 

所以在定義這樣使得類的功能函數「Inline」。因此,如果我們將這個頭文件包含在兩個.cpp文件中,是否會導致「多重定義錯誤」?在類定義中定義類似這樣的函數是不好的做法嗎?

回答

2

這不是不好的做法(實際上它很平常),它不會導致多重定義錯誤。內聯函數永遠不會導致多重定義錯誤,這是內聯的含義之一。

+0

因此,只要函數很小,在頭文件中定義函數沒有什麼問題嗎? – starkk92

+0

@ starkk92我同意這一點,但它是一種風格的東西,所以其他人可能會不同意。 – john

+0

由於在問題中沒有提及'inline',因此可以更清楚地區分* inline *和'inline'。 –

0

在hpp文件中定義(內聯)函數是合法的。請注意,有些人更喜歡在像「inl.hpp」這樣的專用擴展下收集,但這只是一種風格偏好。

0

當你編寫模板類/方法時,這不是一個不好的做法。

inline ing方法可以幫助您遵守一個定義規則。

對於模板類,您應該在頭文件中使用inline方法(也可以顯式實例化它們以避免使用inline -ing)。

壞事約inline方法是,修改每個inline -ed方法之後,使用該方法,各單位必須再次重新編譯,但如果你在一個.cpp文件編譯器移動它們可以使一個目標文件,並重新使用爲許多翻譯單位。

因此,您決定是否需要執行inline(如果可能的話)。

1

從實現中分離原型(即類的聲明,其功能,類型)的約定來自設計和性能兩個角度。

  • 類型檢查和編譯你的家屬更便宜。某些使用你的類的東西可以在不知道你的實現的情況下安全編譯。

  • 每次編譯這些依賴項時,編譯器都不需要分析和重新編譯相同的信息。

的是要記住它真正的意思與你在C++中的文件的頂部寫#include:「採取一些其他文件的所有內容,並把他們在這裏」這意味着因此,如果您在遍佈代碼庫的很多地方使用類,那麼它每次都會被解析,並在該編譯單元的上下文中重新編譯。

這也正是爲什麼你必須模板班線在頭文件中的放的實現;編譯器需要爲每個不同的模板實例化(因爲這就是模板所關注的)重新解析和編譯類。

要直接回答你的問題: *不,你不會得到一個多重定義的錯誤。 *也許,有些人會認爲它從設計的角度回練(其他人不會) *你可能看到表現的差異(雖然不一定是降級,因爲我相信 - 雖然我可能是錯的),儘管如此,編譯純文本頭庫仍然會更快。

如果你的實現很長,可能要避免這樣做,這個類經常在代碼庫中使用,並且會經常發生變化。

要進一步閱讀,可能需要檢查「預編譯頭文件」。

5

這是一個不好的做法,原因如下:如果您需要更改代碼,讓我們說在一個簡單的setter中添加一個跟蹤(他們通常在.h中);那麼您將需要重新編譯包含更改(以及任何依賴項)的所有CPP文件。在我目前的項目中,可能會丟失1小時。如果以後需要添加另一個跟蹤,那麼另一個等快速鬆動1-2天或正在等待編譯器工作。

如果您將代碼放在CPP中,那麼您只需重新鏈接即可,而這隻需幾分鐘。你的項目今天可能很小,但誰知道在幾年內。這只是一個好習慣。

另一個(不是很好)的原因是,如果你搜索你的代碼庫中的字符串「:: MyFonction」,你不會在聲明中找到它,因爲沒有「::」(我們只需要實現)。但是,好的IDE應該使用上下文搜索而不是字符串搜索來找到它。