介紹
- 在函數返回類型前加上關鍵字inline就可以將函數指定爲內聯函數。
內聯函數可避免函數調用開銷。因爲內聯函數將在程序每個調用點上“內聯地”展開,如
cout << IsIntEqual( 10, 10 ) << endl;
在編譯時將展開爲cout << (static_cast<bool>(a==b)
。inline bool IsIntEqual( int a, int b ) { return static_cast<bool>( a == b ); }
- 內聯函數適用於優化小的,只有幾行的而且經常被調用的函數。
- 把內聯函數放入頭文件。內聯函數的定義對編譯器而言必須是可見的,僅有函數原型是不夠的;因爲內聯函數會在調用處展開,所有隻要使用了內聯函數的地方,就有一份內聯函數的代碼,把內聯函數放入頭文件,能保證所有調用的地方展開的代碼是相同的;在頭文件中加入或修改內聯函數,使用了此頭文件的所有源文件必須重新編譯。
普通函數的內聯
普通函數的內聯只需要在函數返回值前加上關鍵字inline即可。內聯函數的前向聲明關鍵字inline好像可以省略(編譯運行沒問題,未深度證實)
//前身聲明 inline bool IsIntEqual( int a, int b );
bool IsIntEqual( int a, int b );
int main()
{
cout << IsIntEqual( 10, 10 ) << endl;
return 0;
}
inline bool IsIntEqual( int a, int b )
{
return static_cast<bool>( a == b );
}
類成員函數的內聯
- 在類內部定義的成員函數,將自動作爲inline處理。
- 也可以顯示的在成員函數返回值前加inline。在類成員聲明、定義處任意一個地方指定了inline或兩者都指定,都可以使其成爲內聯函數。
- 像其他inline一樣,inline成員函數的定義必須在調用該函數的每個源文件中可見。不在類定義體內定義的inline成員函數,其定義通常應放在有類定義的同一頭文件中(要不然會出現無法找到相應符號的鏈接錯誤)。
例子:
class InlineTest
{
public:
//在類聲明中定義函數,隱式地成爲內聯函數
int get1() const
{
return 1;
}
//顯示指定inline,定義在類聲明外部
inline int get2() const;
//類聲明中未指定inline,但在類聲明外部會顯示指定
int get3() const;
//在類聲明及類聲明外部都顯示指定
inline int get4() const;
};
int InlineTest::get2() const
{
return 2;
}
inline int InlineTest::get3() const
{
return 3;
}
inline int InlineTest::get4() const
{
return 4;
}
模板函數的內聯
函數模板可以用與非模板函數一新的方式聲明爲inline,規則也一樣。說明符放在形參表之後,返回類型之前,不能放在關鍵字template之前,
template<class T>
class InlineTest
{
public:
//在類聲明中定義函數,隱式地成爲內聯函數
T get1() const
{
return 1;
}
//指定inline,定義在類聲明外部
inline T get2() const;
//類聲明中未指定inline,但在類聲明外部會指定
T get3() const;
//在類聲明及類聲明外部都指定
inline T get4() const;
};
template<class T>
T InlineTest<T>::get2() const
{
return 2;
}
template<class T>
inline T InlineTest<T>::get3() const
{
return 3;
}
template<class T>
inline T InlineTest<T>::get4() const
{
return 4;
}