IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++】之内联函数(inline) -> 正文阅读

[C++知识库]【C++】之内联函数(inline)

目录

一.概念

二.特性

三.类内成员函数具有内联属性

四.内联函数与宏函数的区别

一.概念

用inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数可以提升程序运行的效率。

为何会有内联函数?

在C语言中,有#define宏这个概念,在宏内,是可以写函数的,我们称之为宏函数。内联函数可以看作是宏函数的升级版本,将宏函数的优点保留,将缺点去掉,这就是内联函数

inline int func()
{
	int a = 1, b = 2;
	return a + b;
}

int main()
{
	int ret = func();
	return 0;
}

二.特性

1.内联函数是一种以空间来换取时间的做法,省区调用函数的额外开销,内联函数会直接在函数调用处把原函数拷贝过来,所以如果函数代码很长或者很复杂,不适合转变为内联函数。

举例:假设一个函数有100行,整个程序需要调用这个函数1w次

不使用内联函数:整个程序代码量:程序代码+1w+100(行)

使用内联函数:整个程序代码量:程序代码+1w*100(行)

如果将这种大函数当作内联函数来使用的话,会使代码量暴增,空间消耗急剧增加!

2.inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体过大,编译器优化时会忽略掉内联。

也就是说当你给一个函数前面写上inline,此时这个函数确确实实拥有了内联属性,但这只是一个建议,编译器具体是否将这个函数在调用处展开,这个取决于编译器的优化,如果编译器认为你的inline函数过大,便不会展开,但是注意,这里仅仅只是不会当作内联函数去处理,而这个函数的内联属性还是存在的。(之后会有这方面的例子)

3.内联函数不能声明与定义分离,如果分离,必会发生链接错误。

因为编译器对于inline的处理,是将inline函数直接展开到调用处,从而inline函数这个函数地址就不需要放在符号表里面了。也就是说,当一个函数有了内联属性,函数地址就不会写入符号表,其他文件调用函数需要通过符号表中的函数地址来匹配从而找到函数定义,这时就找不到了,由于链接不到,结果就会引发链接错误

三.类内成员函数具有内联属性

类内的成员函数,如果这个成员函数定义在类内(注意是定义而不是声明),编译器可能会将其当成内联函数处理。

一但这个类内的成员函数的声明与定义分离开了,就不会具有内联属性。

这样的好处是什么呢?

答:可以实现将小函数直接定义在类内!这样由于编译器会将其当作为内联函数,如果把类写在一个头文件下,他的成员函数的定义也是在头文件下的,此时如果多个.cpp文件都需要引用这个头文件,那么这些成员函数就会在许多个.cpp中都定义了一次,由于这个定义的函数编译器把他当作为内联函数,函数地址不会写入符号表,就不会发生成员函数之间的冲突

看到了吧,上面这个图,打印的是头文件里定义的函数,说明在引用头文件后,编译器在编译时的预处理阶段将头文件展开后,.h文件的成员函数定义就被展开到了这个main.cpp中,然后又因为成员函数有内联属性,所以不会把func函数地址写入符号表,.h定义的func和func.cpp定义的func就不会冲突,然后main.cpp直接把头文件的func函数拷贝到了调用的地方,打印出了hello inline

上图也可以说明,上面inline特性的第2点,如果把这个成员函数写的非常复杂,仍然不会发生冲突,因为虽然函数很大,编译器优化的时候没有在调用处展开,但是这个成员函数是在类内定义的!所以函数地址不会写入符号表,直接调用展开的头文件定义的func,最终打印hello inline

上图展示了,将成员函数分开写,直接报错!成员函数定义与声明一但分离,立即失去内联属性,函数地址全部写入符号表,符号表内存在两个func,且这俩func一模一样无法发生函数重载,最终结果:冲突报错,这属于链接错误,在链接的时候编译器不知道链接具体哪一个

四.内联函数与宏函数的区别

宏的优缺点:

???????优点:1.提高代码的复用性

??????????????????2.提高性能,减少创建/销毁栈帧的消耗

? ? ? ?缺点:1.不方便调试

? ? ? ? ? ? ? ? ? 2.代码可读性差,容易出错

? ? ? ? ? ? ? ? ? 3.没有安全类型检查

内联函数与宏函数的区别:

1. 内联函数可以调试,而宏定义不可以。

2. 编译器会对内联函数作语法检查,而宏定义不会。

3. 内联函数可以访问类的成员变量,宏定义不能。

4. 在类中声名同时定义的成员函数,拥有内联属性。

5. 内联函数是函数,宏不是函数。

6. 内联函数将代码直接插入调用处,减少普通函数调用资源,宏是在代码调用处不加任何验证的简单替换。

内联函数的出现,避免了宏函数的缺点,同时拥有宏函数的优点。

在C++中,能使用const、inline、enum来代替宏,就不使用宏。

这一篇详细讲述了inline以及inline代替宏函数,在下一篇就来叙述一下C++中,const的用法

C++和C语言中的const有什么区别,如何用const来代替#define定义的宏常量!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 18:34:21  更:2022-07-20 18:35:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 22:01:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码