C++內聯函數通常是跟類一起使用。如果一個函數是內聯的,那么在編譯時,編譯器會把該函數的代碼副本放在每個調用該函數的地方。對內聯函數進行任何修改,都需要重新編譯函數的所有客戶端,因為編譯器需要重新更改一次所有的代碼,否則將會繼續使用舊的代碼。
如果想把一個函數定義為內聯函數,需要在函數名前面放關鍵字inline,在調用函數之前需要對函數進行定義。如果已定義的函數多於一行,編譯器會忽略inline限定符。
在類定義中的函數都是內聯函數,即使沒有使用inline說明符。
inline函數的使用:
/*** inline.cpp ***/ #include<iostream> using namespace std; inline int Max(int x,int y) { return (x > y) ? x : y; } int main() { cout << "Max (20,10): " << Max(20,10) << endl; cout << "Max (0,200): " << Max(0,200) << endl; cout << "Max(100,1010): " << Max(100,1010) << endl; return 0; }
運行結果:
exbot@ubuntu:~/wangqinghe/C++/20190807$ ./inline
Max (20,10): 20
Max (0,200): 200
Max(100,1010): 1010
引入內聯函數的目的就是為解決程序中函數調用的效率問題。
程序在編譯器編譯的時候,編譯器將程序中出現的內聯函數的調用表達式用內聯函數的函數體進行替換。而對於其他函數,都是在運行的時候才被替代。其實就是用空間代價來換取節省時間的效果。所以內聯函數一般都是1-5行的小函數。
在使用內聯函數時要留神:
- 在內聯函數中不允許使用循環語句和開關語句;
- 內聯函數的定義必須出現在內聯函數的第一次調用之前;
- 類結構中所在的類說明內部定義的函數是內聯函數。
Tips:只有當函數在只有10行甚至更少時才會被定義為內聯函數。
定義:當函數被聲明為內聯函數之后,編譯器會將其內聯展開,而不是按照通常的函數調用機制進行調用。
優點:當函數體比較小時,內聯該函數可以令目標代碼更加高效。對於存取函數以及其他函數體比較短,性能關鍵的函數,鼓勵使用內聯。
缺點:濫用內聯函數將導致程序變慢,內聯可能使目標代碼量或增或減,這取決於內聯函數的大小。內聯函數非常短小的存取函數通常會減少代碼大小,但內聯一個相當大的函數將戲劇性的增加代碼大小。現代處理器由於更好的指令緩存,小巧的代碼往往執行更快。
結論:一個較為合理的經驗准則是,不要超過10行的函數。謹慎對待析構函數,析構函數往往比其表面看起來更長,因為有隱含的成員和基類析構函數被調用。
內聯那些包含循環或switch語句的函數往往得不償失。
有些函數即使聲明為內聯也不一定會被編譯器內聯,這點很重要。比如虛函數和遞歸函數就不會被正常內聯。通常,遞歸函數不應該聲明成內聯函數(遞歸調用堆棧的展開並不像循環那么簡單,比如遞歸層數在編譯時可能是未知的,大多說編譯器都不支持內聯遞歸函數)。虛函數內聯的主要原因則是想把它的函數體放在類定義內,為了圖個方便,抑或是當作文檔描述其行為,比如精短的存取函數。