為什麼要使用内聯函數:
當程式調用函數時,系統要建立棧空間,保護現場,傳遞參數以及控制程式執行的轉移等等,這些工作需要系統時間和空間的開銷。在有些情況下,函數本身很小很簡單,但是使用頻率很高,程式頻繁的調用這些函數,就會是cpu的大多數開銷花費在建立棧空間,保護現場,程式轉移等工作上
inline 隻是一個标記,要不要把函數轉換為内聯函數還要編譯器說了算,一般在函數中存在switch,for等循環語句,即便聲明了inline編譯器也不會轉換為内聯函數。
改進:
為了提高程式的效率,一般要把代碼嵌入到主函數中,但是又會出現很多重用的代碼,可讀性也會減差
解決:
c++提供了内斂函數
inline函數與宏定義的差別:
(1)内斂函數被調用時,要求實參和形參的類型一緻,另外内聯函數會先對實參表達式求值然後傳遞給形參,宏調用隻是對實參簡單的替換
(2)内聯函數在編譯的時候進行展開,宏定義是在預處理階段替換
不要随便使用内聯函數,因為内聯函數會是函數體增長,一般講函數本身很簡單,代碼短,使用頻率高的函數定義為inline函數
類中的成員函數,類内聲明預設為inline函數,不必要加inline修飾,在類外定義時必須加inline修飾才是内斂函數
類内聲明定義的函數預設為inline函數,
并不是所有的内斂函數都生效.
注意:
将一般函數指定為内聯函數時,隻要在函數的聲明或函數定義時兩者之一做inline聲明即可。
但如果将類函數指定為内斂函數時,應當注意:如果在類體外定義inline函數,則必須将類定義和用到該函數的函數放在同一個檔案中。
下面看一個例子:
//A.h 類聲明檔案
#ifndef _A_H_
#define _A_H_
class A
{
public:
inline int add(int a, int b);
};
#endif //_A_H_:
//A.cpp 類實作檔案
#include "A.h"
inline int A::add(int a, int b)
{
return a+b;
}
//test.cpp 測試檔案
#include "A.h"
#include <iostream>
using namespace std;
int main()
{
A a;
cout<<a.add(2,4)<<endl; //編譯是通不過,因為在這個檔案下找不到用來做替換的内聯函數
return 0;
}
錯誤分析:niline函數是用來進行替換,替換的函數是在本檔案内找,找不到就認為是沒有定義的。即便是在A.cpp中定義了,test.cpp隻能調用A.cpp的函數,而不能拿來做替換。
修改方式有兩種:
(1)在類的聲明中定義
//A.h 類聲明檔案
#ifndef _A_H_
#define _A_H_
class A
{
public:
inline int add(int a, int b)
{
return a+b;
}
};
#endif //_A_H_:
//A.cpp 類實作檔案
#include "A.h"
//test.cpp 測試檔案
#include "A.h"
#include <iostream>
using namespace std;
int main()
{
A a;
cout<<a.add(2,4)<<endl; //6
return 0;
}
分析:有人會說現在test.cpp中也沒有inline函數的實作,其實編譯過程中,include “A.h‘ 是将A.h的代碼替換這條語句,是以,inline函數和調用inline的函數是在一個檔案夾中的
(2)在test.cpp中定義incline函數
//A.h 類聲明檔案
#ifndef _A_H_
#define _A_H_
class A
{
public:
inline int add(int a, int b);
};
#endif //_A_H_:
//A.cpp 類實作檔案
#include "A.h"
//test.cpp 測試檔案
#include "A.h"
#include <iostream>
using namespace std;
inline int A::add(int a, int b)
{
return a+b;
}
int main()
{
A a;
cout<<a.add(2,4)<<endl; //6
return 0;
}