c++inline內聯函數

轉載自牛客網

C++inline內聯函數

典型題目

關於c++的inline關鍵字,以下說法正確的是(D)

A. 使用inline關鍵字的函數會被編譯器在調用處展開
B. 頭文件中可以包含inline函數的聲明
C. 可以在同一個項目的不同源文件內定義函數名相同但實現不同的inline函數
D. 定義在Class聲明內的成員函數默認是inline函數
E. 優先使用Class聲明內定義的inline函數
F. 優先使用Class實現的內inline函數的實現

解釋:

A. 因爲使用 inline 關鍵字的函數只是用戶希望它成爲內聯函數,但編譯器有權忽略這個請求,比如:若此函數體太大,則不會把它作爲內聯函數展開的。

B. 頭文件中不僅要包含 inline 函數的聲明,而且必須包含定義,且在定義時必須加上 inline 。(關鍵字 inline 必須與函數定義體放在一起才能使函數成爲內聯,僅將 inline 放在函數聲明前面不起任何作用)

C. inline 函數可以定義在源文件中,但多個源文件中的同名 inline 函數的實現必須相同。一般把 inline 函數的定義放在頭文件中更加合適。

D. 類內的成員函數,默認都是 inline 的。(定義在類聲明之中的成員函數將自動地成爲內聯函數)

E、F 項無意思,不管是 class 聲明中定義的 inline 函數,還是 class 實現中定義的 inline 函數,不存在優先不優先的問題,因爲 class 的成員函數都是 inline 的,加了關鍵字 inline 也沒什麼特殊的。

小技巧:

內聯函數定義也可以放在源文件中,但有缺陷

內聯函數定義也可以放在源文件中,但此時只有定義的那個源文件可以用它,而且必須爲每個源文件拷貝一份定義(即每個源文件裏的定義必須是完全相同的),當然即使是放在頭文件中,也是對每個定義做一份拷貝,只不過是編譯器替你完成這種拷貝罷了。但相比於放在源文件中,放在頭文件中既能夠確保調用函數是定義是相同的,又能夠保證在調用點能夠找到函數定義從而完成內聯(替換)。對於由兩個文件compute.C和draw.C構成的程序來說,程序員不能定義這樣的min()函數,它在compute.C中指一件事情,而在draw.C中指另外一件事情。如果兩個定義不相同,程序將會有未定義的行爲。爲保證不會發生這樣的事情,建議把inline函數的定義放到頭文件中。在每個調用該inline函數的文件中包含該頭文件。這種方法保證對每個inline函數只有一個定義,且程序員無需複製代碼,並且不可能在程序的生命期中引起無意的不匹配的事情。

Google建議只有當函數只有 10 行甚至更少時纔將其定義爲內聯函數

定義: 當函數被聲明爲內聯函數之後, 編譯器會將其內聯展開, 而不是按通常的函數調用機制進行調用.
優點: 當函數體比較小的時候, 內聯該函數可以令目標代碼更加高效. 對於存取函數以及其它函數體比較短, 性能關鍵的函數, 鼓勵使用內聯。
缺點: 濫用內聯將導致程序變慢. 內聯可能使目標代碼量或增或減, 這取決於內聯函數的大小. 內聯非常短小的存取函數通常會減少代碼大小, 但內聯一個相當大的函數將戲劇性的增加代碼大小. 現代處理器由於更好的利用了指令緩存, 小巧的代碼往往執行更快。
結論: 一個較爲合理的經驗準則是, 不要內聯超過 10 行的函數. 謹慎對待析構函數, 析構函數往往比其表面看起來要更長, 因爲有隱含的成員和基類析構函數被調用!
另一個實用的經驗準則: 內聯那些包含循環或 switch 語句的函數常常是得不償失 (除非在大多數情況下, 這些循環或 switch 語句從不被執行)。
有些函數即使聲明爲內聯的也不一定會被編譯器內聯, 這點很重要; 比如虛函數和遞歸函數就不會被正常內聯. 通常, 遞歸函數不應該聲明成內聯函數.(遞歸調用堆棧的展開並不像循環那麼簡單, 比如遞歸層數在編譯時可能是未知的, 大多數編譯器都不支持內聯遞歸函數). 虛函數內聯的主要原因則是想把它的函數體放在類定義內, 爲了圖個方便, 抑或是當作文檔描述其行爲, 比如精短的存取函數-inl.h文件:

複雜的內聯函數的定義, 應放在後綴名爲 -inl.h 的頭文件中.

內聯函數的定義必須放在頭文件中, 編譯器才能在調用點內聯展開定義. 然而, 實現代碼理論上應該放在 .cc 文件中, 我們不希望 .h 文件中有太多實現代碼, 除非在可讀性和性能上有明顯優勢。
如果內聯函數的定義比較短小, 邏輯比較簡單, 實現代碼放在 .h 文件裏沒有任何問題. 比如, 存取函數的實現理所當然都應該放在類定義內. 出於編寫者和調用者的方便, 較複雜的內聯函數也可以放到 .h 文件中, 如果你覺得這樣會使頭文件顯得笨重, 也可以把它萃取到單獨的 -inl.h 中. 這樣把實現和類定義分離開來, 當需要時包含對應的 -inl.h 即可。

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