在C中卵迂,編譯器使用宏定義節(jié)省編譯時間。在C++中使用內(nèi)聯(lián)函數(shù)來實現(xiàn)同樣的效果绒净。在程序編譯時见咒,編譯器會將內(nèi)聯(lián)函數(shù)調(diào)用處用函數(shù)體替換,這一點類似于C語言中的宏擴展挂疆。
1 什么是內(nèi)聯(lián)函數(shù)
內(nèi)聯(lián)函數(shù)是C++的增強特性之一改览,用來降低程序的運行時間。當內(nèi)聯(lián)函數(shù)收到編譯器的指示時缤言,即可發(fā)生內(nèi)聯(lián):編譯器將使用函數(shù)的定義體來替代函數(shù)調(diào)用語句恃疯,這種替代行為發(fā)生在編譯階段而非程序運行階段。
注意:內(nèi)聯(lián)函數(shù)僅僅是對編譯器的內(nèi)聯(lián)建議墨闲,編譯器是否覺得采取你的建議取決于函數(shù)是否符合內(nèi)聯(lián)的有利條件今妄。如何函數(shù)體非常大,那么編譯器將忽略函數(shù)的內(nèi)聯(lián)聲明鸳碧,而將內(nèi)聯(lián)函數(shù)作為普通函數(shù)處理盾鳞。
2 如何使用內(nèi)聯(lián)函數(shù)
定義函數(shù)時,在函數(shù)的最前面以關鍵字“inline”聲明函數(shù)瞻离,即可使函數(shù)成為內(nèi)聯(lián)聲明函數(shù)腾仅。
Class A
{
Public:
inline int add(int a, int b)
{
return (a + b);
};
}
Class A
{
Public:
int add(int a, int b);
};
inline int A::add(int a, int b)
{
return (a + b);
}
3 為什么使用內(nèi)聯(lián)函數(shù)
在某個程序上下文內(nèi)頻繁地調(diào)用某個函數(shù),其調(diào)用函數(shù)的花銷會有多大:當遇到普通函數(shù)的調(diào)用指令時套利,程序會保存當前函數(shù)的執(zhí)行現(xiàn)場推励,將函數(shù)中的局部變量以及函數(shù)地址壓入堆棧鹤耍,然后再將即將調(diào)用的新函數(shù)加載到內(nèi)存中,這要經(jīng)歷復制參數(shù)值验辞、跳轉(zhuǎn)到所調(diào)用函數(shù)的內(nèi)存位置稿黄、執(zhí)行函數(shù)代碼、存儲函數(shù)返回值等過程跌造,當函數(shù)執(zhí)行完后杆怕,再獲取之前正在調(diào)用的函數(shù)的地址,回去繼續(xù)執(zhí)行那個函數(shù)壳贪,運行時間開銷簡直太多了陵珍。
C++內(nèi)聯(lián)函數(shù)提供了替代函數(shù)調(diào)用的可選方案,通過inline聲明违施,編譯器首先在函數(shù)調(diào)用處使用函數(shù)體本身語句替換了函數(shù)調(diào)用語句互纯,然后編譯替換后的代碼。因此磕蒲,通過內(nèi)聯(lián)函數(shù)留潦,編譯器不需要跳轉(zhuǎn)到內(nèi)存其他地址去執(zhí)行函數(shù)調(diào)用,也不需要保留函數(shù)調(diào)用時的現(xiàn)場數(shù)據(jù)亿卤。
優(yōu)點
- 它通過避免函數(shù)調(diào)用所帶來的開銷來提高你程序的運行速度。
- 當函數(shù)調(diào)用發(fā)生時鹿霸,它節(jié)省了變量彈棧排吴、壓棧的開銷。
- 它避免了一個函數(shù)執(zhí)行完返回原現(xiàn)場的開銷懦鼠。
- 通過將函數(shù)聲明為內(nèi)聯(lián)钻哩,你可以把函數(shù)定義放在頭文件內(nèi)。
缺點
- 因為代碼的擴展肛冶,內(nèi)聯(lián)函數(shù)增大了可執(zhí)行程序的體積街氢。
- C++內(nèi)聯(lián)函數(shù)的展開是在編譯階段,這就意味著如果你的內(nèi)聯(lián)函數(shù)發(fā)生了改動睦袖,那么就需要重新編譯代碼珊肃。
- 當你把內(nèi)聯(lián)函數(shù)放在頭文件中時,它將會使你的頭文件信息變多馅笙,不過頭文件的使用者不用在意這些伦乔。
- 有時候內(nèi)聯(lián)函數(shù)并不受到青睞,比如在嵌入式系統(tǒng)中董习,嵌入式系統(tǒng)的存儲約束可能不允許體積很大的可執(zhí)行程序烈和。
4 什么時候使用內(nèi)聯(lián)函數(shù)
在程序設計時,每個函數(shù)都可以聲明為inline皿淋。下面列舉一些有用的建議:
- 當對程序執(zhí)行性能有要求時
- 當你想宏定義一個函數(shù)時
- 在類內(nèi)部定義的函數(shù)會默認聲明為inline函數(shù)招刹,這有利于類實現(xiàn)細節(jié)的隱藏恬试。
5 注意
- 內(nèi)聯(lián)聲明只是一種對編譯器的建議,編譯器是否采用內(nèi)聯(lián)措施由編譯器自己來決定疯暑。甚至在匯編階段或鏈接階段训柴,一些沒有inline聲明的函數(shù)編譯器也會將它內(nèi)聯(lián)展開。
- 編譯器的內(nèi)聯(lián)看起來就像是代碼的復制與粘貼缰儿,這與預處理宏是很不同的:宏是強制的內(nèi)聯(lián)展開畦粮,可能將會污染所有的命名空間與代碼,將為程序的調(diào)試帶來困難乖阵。
- 所有類中定義的函數(shù)都默認聲明為inline函數(shù)宣赔,因此我們不用顯示地去聲明inline。虛函數(shù)不允許內(nèi)聯(lián)瞪浸。
- 雖然說模板函數(shù)放在頭文件中儒将,但它們不一定是內(nèi)聯(lián)的。(不是說定義在頭文件中的函數(shù)都是內(nèi)聯(lián)函數(shù))对蒲。