Loading

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

posted @ 2019-09-15 14:07  Vel'Koz  阅读(972)  评论(1编辑  收藏  举报