C++inline函数的特性你了解吗

目录
  • 一.inline的作用(内联函数)
  • 二.inline的实现(注意debug模式下内联函数不会展开)
  • 三.使用inline的注意事项
  • 四.inline和预处理的区别
  • 总结

一.inline的作用(内联函数)

我们使用关键字inline和函数定义一起就可以创建一个内联函数,它的作用就是减少函数调用的开销,假如我们的程序中有一个函数会频繁的被调用,这样使程序的运行速度十分缓慢,那么我们使用内联函数,就可以解决这种问题,提高程序的运行效率.

内联函数的定义:

inline void add(int a, int b){
    return a+b;
}

上面这个就是一个内联函数,假如我们的程序中频繁使用add操作时,将其声明为内联函数就可以减少调用开销提高效率.

注意: 

1.inline关键字是一种"用于实现的关键字",而不是"用于声明的关键字", 换句话说inline只有放在函数的定义前,才有可能使该函数成为内联函数,放在函数声明前无效.

2.另外一点是:在c++的类中定义的成员函数默认就是内联函数,但前提是在类中定义,因为我们正常的定义类的方式是在头文件中声明类的成员变量和成员函数,在原文件中对类的成员函数进行定义,此时成员函数的定义发生在类外,所以自然就不再是内联函数了,如果还要让其成为内联函数,就需要我们手动添加inline.

3.至于第一点中我为什么要说可能使该函数成为内联函数,是因为inline是一种推荐型关键字,他并不保证该函数一定会成为内联函数,而是编译器在编译的时候获取有inline建议的函数对其规模,内容,方法等要素进行判断,如果满足编译器要求该函数会成为内联函数,反之不会成为内联函数,因此成不成内联函数完全由编译器说了算.

二.inline的实现(注意debug模式下内联函数不会展开)

既然内联函数可以减小函数的调用开销,那么他是怎么实现的呢?非常简单,我们在所有调用内联函数的地方将其代码展开,这样虽然会使代码的的量增加,但是减少了调用的开销,是一种典型的空间换时间的做法.

我们将编译器调到Release模式下使用内联函数,在汇编指令下就能看见其实现的方式.

源码:

#include<iostream>
using namespace std;
inline int add(int a, int b) {
	return 0;
}
int main() {
	int b=add(1, 2);
	cout << b << endl;
	return 0;
}

(debug模式)反汇编:

在debug模式下我们可以清楚的看到,在程序运行到add函数时,进行了2和1两个参数的压栈,以及add函数的调用.

(Release模式)反汇编:

此时我们可以看到,像之前的那种参数压栈,函数调用没有了,那就是内联函数,实现成功了,在这里不会再继续调用add函数了,而是将add函数直接展开,将其代码放在这里直接进行a+b的运算,避免函数的调用,增加其运行效率.

三.使用inline的注意事项

在上面我说到了,使用内联函数是一种消耗空间获得时间的方法,因此我们得把握好其中的度,当程序的规模过大时,其代码的运行的开销已经远远超过我们函数调用的开销时,此时收益非常小,再使用内联函数就没有必要了,并且函数内存在递归或者循环时也不能使用内联函数,编译器也不会将其变为内联函数.

源码:

#include<iostream>
using namespace std;
inline int mul(int a) {//求a的阶乘
	if (a <= 0) {
		return 1;
	}
	return a * mul(a - 1);
}
int main() {
	int b=mul(10);
	cout << b << endl;
	return 0;
}

(Release模式)反汇编:

此时在Release模式的反汇编指令中我们看到mul函数并没有被展开,而是进行了函数调用,说明编译器并没有将其变为内联函数.

四.inline和预处理的区别

我们知道预处理阶段会发生宏替换这一行为,宏替换也就是将代码中用到宏的地方用宏定义的代码或数据与宏进行替换,inline也是将函数中的代码复制到调用内联函数的地方,那么他们有什么区别呢?宏替换只是单纯的替换并不安全,而内联函数在使用的时候,编译器会对内联函数调用的正确性进行判断如果不正确则该操作就不会发生,因此其更加安全,所以在c++中所有的宏代码,都应该使用内联函数进行取代.

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • C++中inline函数详解

    本文主要记录了C++中的inline函数,也就是内联函数,主要记录了以下几个问题: 一.C++为什么引入inline函数? 主要目的:用它代替C语言中表达式形式的宏定义来解决程序中函数调用的效率问题. C语言中的宏定义:#define ExpressionName(var1,var2) (var1+var2)*(var1-var2)这种宏定义,它使用预处理器实现,没有了参数压栈.代码生成等一系列得到操作,因此效率很高.但缺点如下: 仅仅是做预处理器符号表中的简单替换,因此不能进行参数有效性的检测

  • C++知识点之inline函数、回调函数和普通函数

    目录 一.inline内联函数# 1.1 使用# 1.2 编译器对 inline 函数处理步骤# 1.3 优缺点# 1.3.1 优点# 1.3.2 慎用内联# 1.3.3 不宜使用内联# 1.4 虚函数(virtual)可以是内联函数(inline)吗?# 二.回调函数和普通函数# 2.1 什么是回调函数?# 2.2 为什么要使用回调函数?# 回调函数和普通函数有什么区别? 总结 一.inline内联函数# 特征 相当于把内联函数里面的内容写在调用内联函数处: 相当于不用执行进入函数的步骤,直接

  • C++ inline内联函数详解

    函数是一个可以重复使用的代码块,CPU 会一条一条地挨着执行其中的代码.CPU 在执行主调函数代码时如果遇到了被调函数,主调函数就会暂停,CPU 转而执行被调函数的代码:被调函数执行完毕后再返回到主调函数,主调函数根据刚才的状态继续往下执行. 一个 C/C++ 程序的执行过程可以认为是多个函数之间的相互调用过程,它们形成了一个或简单或复杂的调用链条,这个链条的起点是 main(),终点也是 main().当 main() 调用完了所有的函数,它会返回一个值(例如return 0;)来结束自己的生

  • C++ 内联函数inline案例详解

    使用函数能够避免将相同代码重写多次的麻烦,还能减少可执行程序的体积,但也会带来程序运行时间上的开销. 函数调用在执行时,首先要在栈中为形参和局部变量分配存储空间,然后还要将实参的值复制给形参,接下来还要将函数的返回地址(该地址指明了函数执行结束后,程序应该回到哪里继续执行)放入栈中,最后才跳转到函数内部执行.这个过程是要耗费时间的. 另外,函数执行 return 语句返回时,需要从栈中回收形参和局部变量占用的存储空间,然后从栈中取出返回地址,再跳转到该地址继续执行,这个过程也要耗费时间. 总之,

  • c++内联函数(inline)使用详解

    介绍内联函数之前,有必要介绍一下预处理宏.内联函数的功能和预处理宏的功能相似.相信大家都用过预处理宏,我们会经常定义一些宏,如 复制代码 代码如下: #define TABLE_COMP(x) ((x)>0?(x):0) 就定义了一个宏. 为什么要使用宏呢?因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方.这种转移操作要求在转去执行前要保存现场并记忆执行的地址,转回后要恢复现场,并按原来保存地址继续执行.因此,函数调

  • c++中的内联函数inline用法实例

    问题描述:类中成员函数缺省默认是内联的,如果在类定义时就在类内给出函数定义,那当然最好.如果在类中未给出成员函数定义,而又想内联该函数的话,那在类外要加上 inline,否则就认为不是内联的.内联函数的inline要加在函数前面,不可以加在声明前面. class A { public:void Foo(int x, int y) { } // 自动地成为内联函数 } //正确写法: // 头文件 class A { public: void Foo(int x, int y); } // 定义文

  • C++inline函数的特性你了解吗

    目录 一.inline的作用(内联函数) 二.inline的实现(注意debug模式下内联函数不会展开) 三.使用inline的注意事项 四.inline和预处理的区别 总结 一.inline的作用(内联函数) 我们使用关键字inline和函数定义一起就可以创建一个内联函数,它的作用就是减少函数调用的开销,假如我们的程序中有一个函数会频繁的被调用,这样使程序的运行速度十分缓慢,那么我们使用内联函数,就可以解决这种问题,提高程序的运行效率. 内联函数的定义: inline void add(int

  • JavaScript函数的特性与应用实践深入详解

    本文实例讲述了JavaScript函数的特性与应用实践.分享给大家供大家参考,具体如下: 函数用于指定对象的行为.所谓的编程,就是将一组需求分解为一组函数和数据结构的技能. 1 函数对象 JavaScript 函数就是对象.对象是名值对的集合,它还拥有一个连接到原型对象的链接.对象字面量产生的对象连接到 Object.prototype,而函数对象连接到 Function.prototype(这个对象本身连接到 Object.prototype).每个函数在创建时会附加两个隐藏属性:函数的上下文

  • C++简明分析inline函数的使用

    目录 inline函数 实例 要点 建议 inline函数 当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等, 这些工作需要系统时间和空间的开销. 请看如下程序段,读入一行字符串,逐个判断是否为数字字符: #include<iostream> using namespace std; bool IsNumber(char ch) { return ch>= ʹ0ʹ && ch <= ʹ9ʹ ? 1 : 0; } int main(

  • 在JavaScript中使用inline函数的问题

    前段时间被IE和JavaScript脚本引擎的Memory Leak问题弄得郁闷坏了,不过幸好现在总算是柳暗花明了,并且找到了一些IE中使用脚本避免ML问题的方法.继续研究JavaScript的编写,有发现一些不算ML问题,但是可以节约IE内存使用的方法,在此和大家讨论讨论. 我们在JavaScript中编写代码,对于定义函数的语句: function foo(){    // TODO: . . .    return x;} 可以说是在熟悉不过了.当然除了这种定义函数的方法,我们还有另外几种

  • C++深入探索内联函数inline与auto关键字的使用

    目录 1.内敛函数 1.1问题引入 1.2内联函数的概念 1.3内敛函数的特性 2.auto关键字 2.1 auto简介 2.2 auto的使用细则 2.3 auto不能推导的场景 2.4 auto与新式for循环使用 1.内敛函数 1.1问题引入 我们在使用C语言中我们都学过函数,我们知道函数在调用的过程中需要开辟栈帧.如果我们需要频繁的调用一个函数,假设我们调用10次Add()函数,那我们就需要建立10次栈帧.我们都知道在栈帧中要做很多事情,例如保存寄存器,压参数,压返回值等等,这个过程是很

  • 内联函数inline与宏定义深入解析

    内联函数的优越性:一:inline定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换(像宏定义一样展开),没有了调用的开销,效率很高.二:类的内敛函数是一个真正的函数.三:使用内联函数inline可以完全取代表达式形式的宏定义. 例子: 复制代码 代码如下: Class A{public:int readTest(){return nTest:}void setTest(int i);};inline void A::setTest(int i){nTest=i;}; 说明:类A

  • 探讨C++中不能声明为虚函数的有哪些函数

    常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数. 多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层 函数不属于成员函数,是不能被继承的 2.为什么C++不支持构造函数为虚函数? 这个原因很简单,主要是从语义上考虑,所以不支持.因为构造函数本来就是为了

  • kotlin Standard中的内联函数示例详解

    let.with.run.apply.also.takeIf.takeUnless.repeat函数的使用 kotlin Standard.kt文件中,提供了一些内联函数,这些内联函数可以减少代码量,在使代码优美的同时,打打提高开发效率.它们分别为: run.with.let.also.apply let let函数的定义如下: public inline fun <T, R> T.let(block: (T) -> R): R = block(this) 默认当前这个对象作为闭包的it

随机推荐