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;。可想而知,越復雜的函數體內聯展開越困難。

由此也引出了內聯函數定義的特點:

  • 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM