目錄
爲什麼要引入內聯函數?
inline函數推出的目的,是爲了彌補宏定義的缺點,同時又能很好的繼承宏的優點。用內聯函數替代宏定義,來解決程序中函數調用的效率問題。
內聯函數和宏定義的區別
- 內聯函數是再編譯時展開的,宏是在預編譯時展開的。
- 在編譯的時候,內聯函數是直接鑲嵌到目標代碼中的,而宏只是一個簡單的文本替換。
- 宏不是函數,但內聯函數是函數。
- 內聯函數因爲自身是函數,可以完成諸如,類型檢測,語句是否正確等編譯功能,但宏不行,宏只能機械的進行替換。
- 宏沒有內聯函數穩定,容易出現二義性的歧義
爲什麼內聯函數可以取代宏定義且比宏好?
- 內聯函數和宏一樣,都可以直接將定義的部分放入目標代碼中去,沒有調用的開銷,效率都很高
- 類的內聯函數,是個函數,編譯器在調用它的時候,會去檢測內聯函數的參數類型、語句是否正確等狀況,消除了調用報錯的風險,而這些是宏沒有的。
- 內聯函數既然是函數,那麼,可以準確的使用類的成員對象,而宏不可以(因爲宏無法將this指針放在合適的位置)。
相對於宏內聯函數獨有的使用場景
內聯函數既然是函數,那麼,可以準確的使用類的成員對象,而宏不可以(因爲宏無法將this指針放在合適的位置)。
比如如下的,用內聯函數可以調用類的私有保護成員:
#include <stdio.h>
#include <iostream>
class test
{
public:
void setnum(int num);
private:
int num;
};
inline void test::setnum(int i)
{
printf("i=%d\n",i);
}
int main()
{
test A;
A.setnum(5);
system("pause");
return 0;
}
運行如下:
存疑
經過我的一個小測試,宏也可以跟着this進行更改啊!
#include <stdio.h>
#include <iostream>
#define Pr(i) num = i
class test
{
public:
void sets(int i)
{
Pr(i);
}
void prsets()
{
printf("%d\n", num);
}
private:
int num;
};
int main()
{
test A,B;
A.sets(5);
A.prsets();
B.sets(3);
B.prsets();
A.prsets();
system("pause");
return 0;
}
運行如下:
爲什麼不能將所有函數都定義成內聯函數?
利用只有一個,防止開銷過大:
- 如果函數體的代碼比較長,會使內聯函數的消耗過大
- 如果出現循環,同樣,也會使內聯函數的消耗過大
- 如果把構造函數或者析構函數設置爲內聯函數的時候,要小心,構造、析構函數會不會有“偷偷”操作的行爲,比如,不僅會把當前的構造函數執行一遍,也會把繼承的構造函數,也執行一遍,這樣的話,也會使開銷大大增加!
好在編譯器在執行內聯函數的時候,會先作檢查,能按內聯函數那樣高效率的完成的就執行,不能的話,就自動轉化爲普通函數來執行。