C++:inline

inline

inline是C++提供的一個關鍵字,它用於函數定義以前,表示把函數定義爲內聯函數。內聯函數的含義是:在函數調用點把函數體直接展開,取代函數調用。程序員

inline int getZero() {
    return 0;
}
int a = getZero();

若是上述函數沒有定義爲inline,那麼在聲明a時,程序實際上的工做是,把getZero()函數壓入棧中,執行函數獲得返回值0並出棧,最後把0賦值給a。在定義爲inline以後,編譯器會把做爲內聯函數的函數體在調用點,也就是在聲明a時展開,直接獲得結果0並賦值給a,省去了函數入棧和出棧的調用過程,提高了性能。函數

那麼若是是複雜一點的內聯函數呢?性能

inline int get(int a, int b, int c, int x) {
    return (a * x + b) * x +c;
}
int b = get(1, 2, 1, 4);

比起以前的getZero()get()函數多了許多運算,它在調用點也會被展開爲int b = (1 * 4 + 2) * 4 + 1;。可想而知,越複雜的函數體內聯展開越困難。code

由此也引出了內聯函數定義的特色:遞歸

  • inline關鍵字對編譯器起建議做用,是否內聯編譯由編譯器決定。
  • inline關鍵字出如今函數聲明處不起做用,出如今函數定義時有效。
  • 邏輯複雜的函數定義爲內聯是無心義的,如嵌套調用、遞歸等。
  • 類內定義的函數都是隱式內聯的,類外定義須要顯式加上inline關鍵字。
// inline無心義
inline int f1(int x) {
    if (x == 0 || x== 1) return 1;
    return f(x - 1) + f(x - 2);
}

// inline無心義
inline int f2();

class LiF {
public:
    LiF() = default;
    LiF(int _lif);
    void set(int _lif) { lif = _lif; } // 類內隱式內聯
    int get();
private:
    int lif;
}

LiF::LiF(int _lif): lif(_lif) {} // 無內聯

inline int LiF::get() { return lif; } // 類外顯式內聯

既然內聯能夠提升效率,那爲何不把全部函數都定義爲內聯呢?這個問題也不難解答。內聯的前提是能夠在調用點展開,顯然以前提到的複雜函數時沒法展開的;而若是某次內聯函數執行消耗的時間遠長於調用的消耗,那麼此次內聯也是失敗的。再者,程序效率提高的背後必然有更大的內存消耗,內聯帶來的效率提高是經過複製代碼到調用點實現的,這顯然就增長了代碼量。那麼這就要求程序員謹慎地使用inline內存

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息