溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++內(nèi)聯(lián)函數(shù)(inline)

發(fā)布時間:2020-07-29 06:45:02 來源:網(wǎng)絡 閱讀:255 作者:夢T醒 欄目:編程語言

Tip1:
只有當函數(shù)只有 10 行甚至更少時才將其定義為內(nèi)聯(lián)函數(shù).
定義: 當函數(shù)被聲明為內(nèi)聯(lián)函數(shù)之后, 編譯器會將其內(nèi)聯(lián)展開, 而不是按通常的函數(shù)調(diào)用機制進行調(diào)用.
優(yōu)點: 當函數(shù)體比較小的時候, 內(nèi)聯(lián)該函數(shù)可以令目標代碼更加高效. 對于存取函數(shù)以及其它函數(shù)體比較短, 性能關鍵的函數(shù), 鼓勵使用內(nèi)聯(lián).
缺點: 濫用內(nèi)聯(lián)將導致程序變慢. 內(nèi)聯(lián)可能使目標代碼量或增或減, 這取決于內(nèi)聯(lián)函數(shù)的大小. 內(nèi)聯(lián)非常短小的存取函數(shù)通常會減少代碼大小, 但內(nèi)聯(lián)一個相當大的函數(shù)將戲劇性的增加代碼大小. 現(xiàn)代處理器由于更好的利用了指令緩存, 小巧的代碼往往執(zhí)行更快。
> 結論: 一個較為合理的經(jīng)驗準則是, 不要內(nèi)聯(lián)超過 10 行的函數(shù). 謹慎對待析構函數(shù), 析構函數(shù)往往比其表面看起來要更長, 因為有隱含的成員和基類析構函數(shù)被調(diào)用! 另一個實用的經(jīng)驗準則: 內(nèi)聯(lián)那些包含循環(huán)或 switch 語句的函數(shù)常常是得不償失 (除非在大多數(shù)情況下, 這些循環(huán)或 switch 語句從不被執(zhí)行). 有些函數(shù)即使聲明為內(nèi)聯(lián)的也不一定會被編譯器內(nèi)聯(lián), 這點很重要; 比如虛函數(shù)和遞歸函數(shù)就不會被正常內(nèi)聯(lián). 通常, 遞歸函數(shù)不應該聲明成內(nèi)聯(lián)函數(shù).(遞歸調(diào)用堆棧的展開并不像循環(huán)那么簡單, 比如遞歸層數(shù)在編譯時可能是未知的, 大多數(shù)編譯器都不支持內(nèi)聯(lián)遞歸函數(shù)).
虛函數(shù)不能定義為內(nèi)聯(lián)函數(shù)的原因:
inline是在編譯器將函數(shù)類容替換到函數(shù)調(diào)用處,是靜態(tài)編譯的。而虛函數(shù)是動態(tài)調(diào)用的,在編譯器并不知道需要調(diào)用的是父類還是子類的虛函數(shù),所以不能夠inline聲明展開,所以編譯器會忽略
Tip2:
-inl.h文件:復雜的內(nèi)聯(lián)函數(shù)的定義, 應放在后綴名為 -inl.h 的頭文件中. 內(nèi)聯(lián)函數(shù)的定義必須放在頭文件中, 編譯器才能在調(diào)用點內(nèi)聯(lián)展開定義. 然而, 實現(xiàn)代碼理論上應該放在 .c 文件中, 我們不希望 .h 文件中有太多實現(xiàn)代碼, 除非在可讀性和性能上有明顯優(yōu)勢. 如果內(nèi)聯(lián)函數(shù)的定義比較短小, 邏輯比較簡單, 實現(xiàn)代碼放在 .h 文件里沒有任何問題.
比如, 存取函數(shù)的實現(xiàn)理所當然都應該放在類定義內(nèi). 出于編寫者和調(diào)用者的方便, 較復雜的內(nèi)聯(lián)函數(shù)也可以放到 .h 文件中, 如果你覺得這樣會使頭文件顯得笨重, 也可以把它萃取到單獨的 -inl.h 中. 這樣把實現(xiàn)和類定義分離開來, 當需要時包含對應的 -inl.h 即可。

關于c++的inline關鍵字,以下說法正確的是()
A.使用inline關鍵字的函數(shù)會被編譯器在調(diào)用處展開
B.頭文件中可以包含inline函數(shù)的聲明
C.可以在同一個項目的不同源文件內(nèi)定義函數(shù)名相同但實現(xiàn)不同的inline函數(shù)
D.定義在Class聲明內(nèi)的成員函數(shù)默認是inline函數(shù)
E.優(yōu)先使用Class聲明內(nèi)定義的inline函數(shù)
F.優(yōu)先使用Class實現(xiàn)的內(nèi)inline函數(shù)的實現(xiàn)

A 如果只聲明含有inline關鍵字,就沒有內(nèi)聯(lián)的效果。 內(nèi)聯(lián)函數(shù)的定義必須放在頭文件中, 編譯器才能在調(diào)用點內(nèi)聯(lián)展開定義. 有些函數(shù)即使聲明為內(nèi)聯(lián)的也不一定會被編譯器內(nèi)聯(lián), 這點很重要; 比如虛函數(shù)和遞歸函數(shù)就不會被正常內(nèi)聯(lián). 通常, 遞歸函數(shù)不應該聲明成內(nèi)聯(lián)函數(shù).
B 內(nèi)聯(lián)函數(shù)應該在頭文件中定義,這一點不同于其他函數(shù)。編譯器在調(diào)用點內(nèi)聯(lián)展開函數(shù)的代碼時,必須能夠找到 inline 函數(shù)的定義才能將調(diào)用函數(shù)替換為函數(shù)代碼,而對于在頭文件中僅有函數(shù)聲明是不夠的。
C 當然內(nèi)聯(lián)函數(shù)定義也可以放在源文件中,但此時只有定義的那個源文件可以用它,而且必須為每個源文件拷貝一份定義(即每個源文件里的定義必須是完全相同的),當然即使是放在頭文件中,也是對每個定義做一份拷貝,只不過是編譯器替你完成這種拷貝罷了。但相比于放在源文件中,放在頭文件中既能夠確保調(diào)用函數(shù)是定義是相同的,又能夠保證在調(diào)用點能夠找到函數(shù)定義從而完成內(nèi)聯(lián)(替換)。 對于由兩個文件compute.C和draw.C構成的程序來說,程序員不能定義這樣的min()函數(shù),它在compute.C中指一件事情,而在draw.C中指另外一件事情。如果兩個定義不相同,程序將會有未定義的行為:為保證不會發(fā)生這樣的事情,建議把inline函數(shù)的定義放到頭文件中。在每個調(diào)用該inline函數(shù)的文件中包含該頭文件。這種方法保證對每個inline函數(shù)只有一個定義,且程序員無需復制代碼,并且不可能在程序的生命期中引起無意的不匹配的事情。
D 正確。 定義在類聲明之中的成員函數(shù)將自動地成為內(nèi)聯(lián)函數(shù),例如: class A { public: void Foo(int x, int y) { ... } // 自動地成為內(nèi)聯(lián)函數(shù) }
EF 在每個調(diào)用該inline函數(shù)的文件中包含該頭文件。這種方法保證對每個inline函數(shù)只有一個定義,且程序員無需復制代碼,并且不可能在程序的生命期中引起無意的不匹配的事情。最好只有一個定義!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI