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 內聯函式的目的是為了減少函式呼叫時間。它是把內聯函式的函式體在編譯器預處理的時候替...