C++中的行內函數(inline)與巨集定義
阿新 • • 發佈:2018-12-16
為什麼要使用行內函數呢?
當我們定義完一個函式之後,實際呼叫的時候,函式體本身會壓入堆疊,主函式再從堆疊裡面把這部分內容提取出來,產生一定的系統開銷,對於大型函式來說,這部分開銷可能相對於函式體本身執行的開銷來說微乎其微。但是如果一個函式僅僅只是為了完成一個特別簡單的功能,比如交換兩個變數的值,亦或是求兩個變數的最大值,這時,呼叫函式的開銷,可能就會大於函式體執行本身了。作為一個追求高效能的程式而言,大量的這種函式呼叫的堆積,勢必會使得整體的效能下降。
例如,下面這個返回a和b最大值的函式,
#include<iostream> using namespace std; int max(int a,int b) { return a > b? a:b; } int main() { int a = 3; int b = 5; cout<<max(a,b)<<endl; }
如果換成行內函數,就在函式定義的時候,前面加上inline即可,然後主函式執行的時候,相當於載入了函式體的內容:
#include<iostream>
using namespace std;
inline int max(int a,int b) {
return a > b? a:b;
}
int main() {
int a = 3;
int b = 5;
cout<<max(a,b)<<endl;
//相當於 cout<<(a>b?a:b)<<endl;
}
從而減小了把max寫成函式的系統額外開銷。本質上是一種犧牲空間複雜度換取時間複雜度的過程。
但是需要注意的是,行內函數不可以直接用於沒有定義的函式宣告。此外,在面向物件程式設計中,定義在類內的成員函式預設定義為行內函數。可以使用所在類的保護成員和私有成員。
行內函數與巨集定義的區別:
巨集定義具有兩個缺點:一是不能除錯,二是隻是進行了簡單的文字替換,如果重複使用的話,可能會出現重定義的情況。而與之相比的話,行內函數就很靈活了。下面的這個例子很生動,
#define SQUARE(X) X*X
巨集定義時通過文字替換開實現的--X是引數的符號標記。
a = square(5.0); //->a=5.0*5.0; b = square(4.5+7.5); //->b=4.5+7.5*4.5+7.5 d = square(c++); //->d=c++*c++
可以看出,對於b,需要使用括號才能正常運算。
#define SQUARE(X) ((X)*(X))
對於c,卻仍遞增了兩次。 因此,巨集定義和行內函數存在本質的區別,轉換的時候應考慮是否轉換後功能是否正常。