天天看點

C++中的INLINE(内聯)函數

inline關鍵字僅僅是對編譯器的建議,編譯器有權力決定一個函數是否在調用處嵌入。因為内聯函數要在調用處展開,編譯器必須能在每一個調用處能看到該函數的定義,是以最好将函數實作放在頭檔案中(而且實作在類定義中的成員函數即便不加inline關鍵字也會自動成為内聯函數)。在實作檔案中該函數之前要加上inline關鍵字的方式是有問題的:如果調用的obj檔案在函數定義之前生成,那麼該處就無法嵌入内聯函數了。如果普通函數需要成為内聯函數,在定義時加上inline關鍵字。

注意:

  1. 包含了遞歸、循環等結構的函數一般不會被内聯。
  2. 虛拟函數一般不會内聯,但是如果編譯器能在編譯時确定具體的調用函數,那麼仍然會就地展開該函數。
  3. 如果通過函數指針調用内聯函數,那麼該函數将不會内聯而是通過call進行調用。
  4. 構造和析構函數一般會生成大量代碼,是以一般也不适合内聯。
  5. 如果内聯函數調用了其他函數也不會被内聯。

如果想要阻止某函數被内聯,可以在函數體前加上 attribute((noinline)) 。 實際上除了上述需要注意的項目,下面這個也同樣重要:

在C++中,内聯函數必須是和函數體申明在一起,才有效。像這樣的申明 Inline Tablefunction(int I);

是沒有效果的,編譯器隻是把函數作為普通的函數申明,我們必須定義函數體。 Inline tablefunction(int I)

{return I*I}; 這樣我們才算定義了一個内聯函數。我們可以把它作為一般的函數一樣調用。但是執行速度确比一般函數的執行速度要快。

個人經驗來說:

在C++中,當有多個函數檔案時,内聯函數的定義與聲明必須放在頭檔案中,在A函數檔案中定義的内聯函數不能在B函數檔案中使用,即使是main函數。

(error:無法解析的外部符号 “bool __cdecl compareIsbn(class Sales_data const &,class Sales_data const &)” ([email protected]@[email protected]@[email protected]),該符号在函數 _main 中被引用)

這種錯誤在編譯時是發現不了的,當程式運作時才會發生,一定要注意!!!

繼續閱讀