內聯函數的深度探究—預處理、const、static與sizeof(四)

目錄

 

爲什麼要引入內聯函數?

內聯函數和宏定義的區別

爲什麼內聯函數可以取代宏定義且比宏好?

相對於宏內聯函數獨有的使用場景

存疑

爲什麼不能將所有函數都定義成內聯函數?


爲什麼要引入內聯函數?

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;
}

運行如下: 

 

爲什麼不能將所有函數都定義成內聯函數?

利用只有一個,防止開銷過大:

  • 如果函數體的代碼比較長,會使內聯函數的消耗過大
  • 如果出現循環,同樣,也會使內聯函數的消耗過大
  • 如果把構造函數或者析構函數設置爲內聯函數的時候,要小心,構造、析構函數會不會有“偷偷”操作的行爲,比如,不僅會把當前的構造函數執行一遍,也會把繼承的構造函數,也執行一遍,這樣的話,也會使開銷大大增加!

好在編譯器在執行內聯函數的時候,會先作檢查,能按內聯函數那樣高效率的完成的就執行,不能的話,就自動轉化爲普通函數來執行。

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章