C C inline 內聯函式

2021-07-25 08:35:37 字數 3308 閱讀 9845

c++關鍵字

外文名

inline

背    景

inline

關鍵字用來定義乙個類

巨集定義define expressionname

取    代

巨集定義在形式上類似於乙個函式

在c&c++中

一、inline

關鍵字用來定義乙個類的

內聯函式,引入它的主要原因是用它替代c中

表示式形式的

巨集定義。

表示式形式的巨集定義一例:

#define expressionname(var1,var2) ((var1)+(var2))*((var1)-(var2))

取代這種形式的原因如下:

1. c中使用define這種形式巨集定義的原因是因為,c語言是乙個效率很高的語言,這種巨集定義在形式及使用上像乙個函式,但它使用

預處理器實現,沒有了

引數壓棧,**生成

等一系列的操作,因此,效率很高,這是它在c中被使用的乙個主要原因。

2. 這種

巨集定義在形式上類似於乙個函式,但在使用它時,僅僅只是做預處理器

符號表中的簡單替換,因此它不能進行引數有效性的檢測,也就不能享受c++

編譯器嚴格型別檢查的好處,另外它的返回值也不能被強制轉換為可轉換的合適的型別,這樣,它的使用就存在著一系列的隱患和侷限性。

3. 在c++中引入了類及類的訪問控制,這樣,如果乙個操作或者說乙個

表示式涉及到類的保護成員或私有成員,你就不可能使用這種巨集定義來實現(因為無法將this

指標放在合適的位置)。

4. inline 推出的目的,也正是為了取代這種表示式形式的

巨集定義,它消除了巨集定義的缺點,同時又很好地繼承了巨集定義的優點。

對應於上面的1-3點,闡述如下:

1. inline 定義的類的

內聯函式

,函式的**被放入

符號表中,在使用時直接進行替換,(像巨集一樣展開),沒有了呼叫的開銷,效率也很高。

int g(int x)

int f()

這樣f會呼叫g,然後g返回x + x給f,然後f繼續把那個值返回給呼叫者。 

如果g是inline的話。f會被直接編譯成。 

int f() 

相當於把g執行的操作直接融合到f裡。這樣減少了呼叫g消耗的時間,但同時也增大了f的尺寸。 

這就是inline函式,也就是所謂的內聯函式。

2. 很明顯,類的內聯函式也是乙個真正的函式,

編譯器在呼叫乙個內聯函式時,會首先檢查它的引數的型別,保證呼叫正確。然後進行一系列的相關檢查,就像對待任何乙個真正的函式一樣。這樣就消除了它的隱患和侷限性。

3. inline 可以作為某個

類的成員函式,當然就可以在其中使用所在類的保護成員及私有成員。

在何時使用inline函式:

首先,你可以使用inline函式完全取代

表示式形式的巨集定義。

另外要注意,

內聯函式一般只會用在函式內容非常簡單的時候,這是因為,內聯函式的**會在任何呼叫它的地方展開,如果函式太複雜,**膨脹帶來的惡果很可能會大於效率的提高帶來的益處。內聯函式最重要的使用地方是用於類的訪問函式。

簡單提一下inline 的使用吧:

1.在類

中定義這種函式:

// 如果在類中直接定義,不需要用inline修飾,編譯器自動化為內聯函式,此說法在《c++ primer》中提及

class classname; // 如果在類中直接定義,不需要用inline修飾,編譯器自動化為內聯函式

.... //此說法在《c++ primer》中提及

....

}

2.在類外定義前加inline關鍵字:

注意:雖然是在類外,但還是在標頭檔案中定義。函式先在類中宣告,在類外定義。

class account  //與1相同

double getbalance(); //在類中宣告

double deposit( double amount );

double withdraw( double amount );

private:

double balance;

};inline double account::getbalance() //在類外定義時新增inline關鍵字

inline double account::deposit( double amount )

inline double account::withdraw( double amount )

此外還有一些規則需注意:

1、inline說明對

編譯器來說只是一種建議,編譯器可以選擇忽略這個建議。比如,你將乙個長達1000多行的函式指定為inline,編譯器就會忽略這個inline,將這個函式還原成普通函式。

2、在呼叫

內聯函式時,要保證內聯函式的定義讓編譯器"看"到,也就是說內聯函式的定義要在標頭檔案中,這與通常的函式定義不一樣。但如果你習慣將函式定義放在cpp檔案中,或者想讓標頭檔案更簡潔一點,可這樣做:

#ifndef someinline_h

#define someinline_h

type example(void);

//........其他函式的宣告

#include"someinlie.cpp" //原始檔字尾名隨編譯器而定

#endif

#include"someinline.h"

inline type example(void)

//...............其他函式的定義

以上方法是通用、有效的,可放心使用,不必擔心在標頭檔案包含cpp檔案會導致編譯錯誤。

---------

但是現在不是這樣了。 

現在的編譯器會自動決定是否對函式進行上面的操作,而不是根據你前面加不加inline。 

但是inline本身還是有另外乙個意義: 

乙個可執行檔案的cpp檔案中乙個函式只能被定義一次。如果你把函式定義在乙個.h檔案中並讓兩個cpp包含就會造成這個函式分別在兩個cpp中被定義產生錯誤。但是inline函式是允許在多個cpp中多次定義的,就解決了這個問題。

mysql 內聯函式 Kotlin內聯函式

內聯函式使用關鍵字內聯宣告,內聯函式的使用增強了高階函式的效能。內聯函式告訴編譯器將引數和函式複製到呼叫站點。虛函式或區域性函式不能宣告為內聯。以下是內聯函式內部不支援的一些表示式和宣告 區域性類宣告 內部巢狀類的宣告 函式表示式 宣告區域性函式 區域性可選引數的預設值 讓我們看一下內聯函式的基本示...

函式之內聯函式

內聯函式 定義 內聯函式是c 為提高程式執行速度所進行的一項改進。常規函式與內聯函式之間的區別不在於編寫方式,而在於c 編譯器如何將他們組合到程式裡。c 函式的編譯 與其他程式的 內聯 了起來,也就是說,編譯器將使用相應的函式 代替函式呼叫。對於內聯函式,程式無需調到另乙個位置處執行 再跳回來,因此...

內聯函式 虛函式

在c 中,inline關鍵字和virtual關鍵字分別用來定義c 中的內聯函式和虛函式,他們在各自的場合都有其各自的應用,下面將簡單介紹他們各自的功能,然後在說明為什麼乙個函式不能同時是虛函式和內聯函式 inline 內聯函式的目的是為了減少函式呼叫時間。它是把內聯函式的函式體在編譯器預處理的時候替...