C 中的inLine函式

2022-09-02 23:36:31 字數 3104 閱讀 8121

(一)inline函式(摘自c++ primer的第三版)

在函式宣告或定義中函式返回型別前加上關鍵字inline即把min()指定為內聯。

inline int min(int first, int secend) ;

inline 函式對編譯器而言必須是可見的,以便它能夠在呼叫點內展開該函式。與非inline函式不同的是,inline函式必須在呼叫該函式的每個文字檔案中定義。當然,對於同一程式的不同檔案,如果inline函式出現的話,其定義必須相同。對於由兩個檔案compute.c和draw.c構成的程式來說,程式設計師不能定義這樣的min()函式,它在compute.c中指一件事情,而在draw.c中指另外一件事情。如果兩個定義不相同,程式將會有未定義的行為:

為保證不會發生這樣的事情,建議把inline函式的定義放到標頭檔案中。在每個呼叫該inline函式的檔案中包含該標頭檔案。這種方法保證對每個inline函式只有乙個定義,且程式設計師無需複製**,並且不可能在程式的生命期中引起無意的不匹配的事情。

(二)內聯函式的程式設計風格(摘自高質量c++/c 程式設計指南)

關鍵字inline 必須與函式定義體放在一起才能使函式成為內聯,僅將inline 放在函式宣告前面不起任何作用

如下風格的函式foo 不能成為內聯函式:

inline void foo(int x, int y); // inline 僅與函式宣告放在一起

void foo(int x, int y){}

而如下風格的函式foo 則成為內聯函式:

void foo(int x, int y);

inline void foo(int x, int y) // inline 與函式定義體放在一起{}

所以說,inline 是一種「用於實現的關鍵字」,而不是一種「用於宣告的關鍵字」。一般地,使用者可以閱讀函式的宣告,但是看不到函式的定義。儘管在大多數教科書中內聯函式的宣告、定義體前面都加了inline 關鍵字,但我認為inline 不應該出現在函式的宣告中。這個細節雖然不會影響函式的功能,但是體現了高質量c++/c 程式設計風格的乙個基本原則:宣告與定義不可混為一談,使用者沒有必要、也不應該知道函式是否需要內聯。

定義在類宣告之中的成員函式將自動地成為內聯函式

例如class a

public:void foo(int x, int y) // 自動地成為內聯函式

將成員函式的定義體放在類宣告之中雖然能帶來書寫上的方便,但不是一種良好的程式設計風格,上例應該改成:

// 標頭檔案

class a

public:

void foo(int x, int y);

// 定義檔案

inline void a::foo(int x, int y){}

慎用內聯

內聯能提高函式的執行效率,為什麼不把所有的函式都定義成內聯函式?如果所有的函式都是內聯函式,還用得著「內聯」這個關鍵字嗎?內聯是以**膨脹(複製)為代價,僅僅省去了函式呼叫的開銷,從而提高函式的執行效率。如果執行函式體內**的時間,相比於函式呼叫的開銷較大,那麼效率的收穫會很少。另一方面,每一處內聯函式的呼叫都要複製**,將使程式的總**量增大,消耗更多的記憶體空間。

以下情況不宜使用內聯:

(1)如果函式體內的**比較長,使用內聯將導致記憶體消耗代價較高。

(2)如果函式體內出現迴圈,那麼執行函式體內**的時間要比函式呼叫的開銷大。類的建構函式和析構函式容易讓人誤解成使用內聯更有效。要當心建構函式和析構函式可能會隱藏一些行為,如「偷偷地」執行了基類或成員物件的建構函式和析構函式。所以不要隨便地將建構函式和析構函式的定義體放在類宣告中。乙個好的編譯器將會根據函式的定義體,自動地取消不值得的內聯(這進一步說明了 inline 不應該出現在函式的宣告中)。

注意點:

內聯函式既能夠去除函式呼叫所帶來的效率負擔又能夠保留一般函式的優點。然而,內聯函式並不是萬能藥,在一些情況下,它甚至能夠降低程式的效能。因此在使用的時候應該慎重。   

1.我們先來看看內聯函式給我們帶來的好處:從乙個使用者的角度來看,內聯函式看起來和普通函式一樣, 它可以有引數和返回值,也可以有自己的作用域,然而它卻不會引入一般函式呼叫所帶來的負擔。另外, 它可以比巨集更安全更容易除錯。   

當然有一點應該意識到,inline   specifier僅僅是對編譯器的建議,編譯器有權利忽略這個建議。那麼編譯器是如何決定函式內聯與否呢?一般情況下關鍵性因素包括函式體的大小,是否有區域性物件被宣告,函式的複雜性等等。   

2.那麼如果乙個函式被宣告為inline但是卻沒有被內聯將會發生什麼呢?理論上,當編譯器拒絕內聯乙個   函式的時候,那個函式會像普通函式一樣被對待,但是還會出現一些其他的問題。例如下面這段**:   

//   filename   time.h   

#include

#include

using   namespace   std;   

class   time   

{   

public:   

inline   void   show()  

{   

for (int   i   =   0;   i<10;   i++)

cout<

另外關於內聯函式還有兩個更令人頭疼的問題。第乙個問題是該如何進行維護。乙個函式開始的時候可能以內聯的形式出現,但是隨著系統的擴充套件,函式體可能要求新增額外的功能,結果內聯函式就變得不太可能,因此需要把inline   specifier去除以及把函式體放到乙個單獨的原始檔中。另乙個問題是當內聯函式被應用在**庫的時候產生。當內聯函式改變的時候,使用者必須重新編譯他們的**以反映這種改變。然而對於乙個非內聯函式,使用者僅僅需要重新鏈結就可以了。 

這裡想要說的是,內聯函式並不是乙個增強效能的靈丹妙藥。只有當函式非常短小的時候它才能得到我們想要的效果,但是如果函式並不是很短而且在很多地方都被呼叫的話,那麼將會使得可執行體的體積增大。最令人煩惱的還是當編譯器拒絕內聯的時候。在老的實現中,結果很不盡人意,雖然在新的實現中有很大的改善,但是仍然還是不那麼完善的。一些編譯器能夠足夠的聰明來指出哪些函式可以內聯哪些不能,但是,大多數編譯器就不那麼聰明了,因此這就需要我們的經驗來判斷。如果內聯函式不能增強行能,就避免使用它!  

C 中的inline函式

在函式名字前面加上inline,該函式就被宣告為內建函式。每當程式中出現對該函式的呼叫時,c 編譯器使用函式體中的代 碼插入到呼叫該函式的語句之處,而不是將流程轉出去,同時用實參代替形參,以便在程式執行時不再進行函式呼叫。引入內建函式的目的就是 消除函式呼叫時系統開銷,以提高執行速度。減少程式執行過...

C 中的inline函式

1 inline函式的處理流程 在函式的呼叫點直接進行 的替換。2 inline函式和普通函式的區別 1 普通函式有函式的堆疊和清棧。2 inline函式由於 的直接展開,所以沒有堆疊和清棧,效率會更高。3 inline函式和巨集的區別 1 巨集在預編譯階段,沒有型別和安全檢查。2 inline函式...

inline函式 C 內聯函式 inline

inline要起作用,必須要與函式定義放在一起,而不是函式的宣告 inline 當編譯器處理呼叫內聯函式的語句時,不會將該語句編譯成函式呼叫的指令,而是直接將整個函式體的 插人呼叫語句處,就像整個函式體在呼叫處被重寫了一遍一樣,在執行時是順序執行,而不會進行跳轉。優點 內聯函式沒有執行函式呼叫的開銷...