美文网首页C++互联网科技程序员
小朋友学C++(20):内联函数

小朋友学C++(20):内联函数

作者: 海天一树X | 来源:发表于2018-06-07 13:54 被阅读27次

一、何谓内联函数

上一节课中,我们分析了这一段函数:

template<class _Ty> inline
        _Ty _Pow_int(_Ty _X, int _Y)
        {unsigned int _N;
        if (_Y >= 0)
                _N = _Y;
        else
                _N = -_Y;
        for (_Ty _Z = _Ty(1); ; _X *= _X)
                {if ((_N & 1) != 0)
                        _Z *= _X;
                if ((_N >>= 1) == 0)
                        return (_Y < 0 ? _Ty(1) / _Z : _Z); }}

这里用到了关键字inline。
inline表示被修饰的函数内联函数。

二、为何使用内联函数

比如有一个要求两个整数的最大值,可以有三种写法:
(1)

a > b ? a : b 

(2)

int max(int a, int b)
{
    return a > b ? a : b;
}

(3)

inline int max(int a, int b)
{
    return a > b ? a : b;
}

第(2)种方法比第(1)种方法,有三个优点:
① 阅读和理解函数 max 的调用,要比读一条等价的条件表达式并解释它的含义要容易得多
② 如果需要做任何修改,修改函数要比找出并修改每一处等价表达式容易得多
③ 函数可以重用,不必为其他应用程序重写代码
但也有一个缺点:
调用函数比求解等价表达式要慢得多。在大多数的机器上,调用函数都要做很多工作:调用前要先保存寄存器,并在返回时恢复,复制实参,程序还必须转向一个新位置执行

C++中支持内联函数,其目的是为了提高函数的执行效率,用关键字 inline 放在函数定义(注意是定义而非声明)的前面即可将函数指定为内联函数,内联函数通常就是将它在程序中的每个调用点上“内联地”展开,假设我们将 max 定义为内联函数,即上面第(3)种方式,那么若调用的代码为

cout << max(a, b) << endl;

则编译时,会自动展开为

cout << (a > b ? a : b) << endl;

从而消除了把 max写成函数的额外执行开销。

三、内联函数与宏的比较

宏本身没有安全检查,纯粹是简单替换,会引起很多语义错误,所以C++倒是提倡用const和内联代替宏。

四、内联函数必须放在函数定义的前面

关键字 inline 必须与函数定义体放在一起才能使函数成为内联,仅将 inline 放在函数声明前面不起任何作用。

如下风格的函数 Foo 不能成为内联函数:

inline void Foo(int x, int y);   // inline 仅与函数声明放在一起   
void Foo(int x, int y)
{
 ...
} 

而如下风格的函数 Foo 则成为内联函数:

void Foo(int x, int y);   
inline void Foo(int x, int y)   // inline 与函数定义体放在一起
{
 ...
} 

而如下风格的函数 Foo 也能成为内联函数:

inline void Foo(int x, int y);   
inline void Foo(int x, int y)   // inline 与函数定义体放在一起
{
 ...
} 

所以说,C++ inline函数是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。
一般地,用户可以阅读函数的声明,但是看不到函数的定义。

五、慎用内联函数

只有当函数只有 10 行甚至更少时才将其定义为内联函数。

当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.
优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.
缺点: 滥用内联将导致程序变慢. 内联可能使目标代码量或增或减, 这取决于内联函数的大小. 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增加代码大小. 现代处理器由于更好的利用了指令缓存, 小巧的代码往往执行更快。
结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数.
谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!
另一个实用的经验准则: 内联那些包含循环或 switch 语句的函数常常是得不偿失 (除非在大多数情况下, 这些循环或 switch 语句从不被执行)。
有些函数即使声明为内联的也不一定会被编译器内联, 这点很重要; 比如递归函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数.(递归调用堆栈的展开并不像循环那么简单, 比如递归层数在编译时可能是未知的, 大多数编译器都不支持内联递归函数)。

TopCoder & Codeforces & AtCoder交流QQ群:648202993
更多内容请关注微信公众号


wechat_public_header.jpg

相关文章

  • 小朋友学C++(20):内联函数

    一、何谓内联函数 上一节课中,我们分析了这一段函数: 这里用到了关键字inline。inline表示被修饰的函数内...

  • 宏定义min

    C++内联函数

  • 白话kotlin:内联函数助你提升运行效率

    什么是内联函数 这个玩意吸取自C++,如下: 内联函数是C++的增强特性之一,用来降低程序的运行时间。当内联函数收...

  • 《C++ Primer Plus》:函数探幽

    本章内容概览 内联函数 引用变量 按引用传递函数参数 默认参数 函数重载 函数模板 内联函数 内联函数是C++为提...

  • 第九章 内联函数

    简介:C++中预处理器宏存在的问题,在C++中如何用内联函数解决这些问题以及使用内联函数的方针和内联函数的工作机制...

  • C++基础-(函数)

    C++基础 函数 内联函数 内联函数非常短的函数适合于内联函数体会到插入到发生函数调用的地方普通函数调用多次也只有...

  • C++内联函数与C语言函数宏

    C++内联函数 什么是内联函数? 在函数的声明和定义前加一个 inline 关键字,这个函数就是内联函数。 通常会...

  • Kotlin 内联函数 inline

    Kotlin 中新增了「内联函数」,内联函数起初是在 C++ 里面的。 那在 Kotlin 中加入内联函数,是有什...

  • ★ 学习笔记:《iOS高级:Swift入门精讲②》第一节 Swi

    前言:本篇仅为视频学习笔记 内联函数 (Inline Function)内联函数在C++这个函数里是有的,那么在s...

  • C++ 的inline关键字

    首先理解内联函数: ​ C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器...

网友评论

    本文标题:小朋友学C++(20):内联函数

    本文链接:https://www.haomeiwen.com/subject/obkgsftx.html