C++ inline内联函数

news2024/9/29 6:40:48

个人主页:Jason_from_China-CSDN博客

所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客

所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客

概念概述

  • 用 inline 修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立栈帧了,就可以提高效率。展开的意思就是不建立栈帧了,直接进行执行,所以本质就是提升效率用的
  • inline 对于编译器而言只是一个建议,也就是说,你加了 inline 编译器也可以选择在调用的地方不展开,不同编译器关于 inline 什么情况展开各不相同,因为C++标准没有规定这个。inline 适用于频繁调用的短小函数,对于递归函数,代码相对多一些的函数,加上 inline 也会被编译器忽略。
  • C语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不方便调试,C++设计了 inline 目的就是为了替代C的宏函数。
  • VS编译器 debug版本下面默认是不展开 inline 的,这样方便调试,debug版本想展开需要设置一下以下两个地方。
  • inline 不建议声明和定义分离到两个文件(所以往往直接定义在头文件),分离会导致链接错误。因为 inline 被展开,就没有函数地址,链接时会出现报错。

补充说明

  1. 内联展开与栈帧

    • 内联函数的展开并不意味着完全不建立栈帧,而是减少了函数调用的额外开销。如果内联函数中涉及复杂的操作,如循环或条件分支,编译器可能会决定不进行内联展开,或者在某些情况下,内联展开可能仍然需要栈帧来保存局部变量和寄存器。
  2. 编译器的 inline 决策

    • 编译器会根据函数的大小、复杂度、调用频率以及优化级别等因素来决定是否进行内联展开。通常,小而简单的函数更可能被内联展开。(也就是如果内联的复杂度过高,会直接展开内联)。
    • 展开内联函数并不意味着函数的代码会被移动到实现文件(.cpp文件)中。实际上,内联函数的定义通常位于头文件(.h或.hpp文件)中,这样编译器在处理每个包含该头文件的源文件时,都能够看到函数的定义,并在每个调用点进行展开。
  3. 宏函数与 inline

    • 宏函数在预处理器阶段进行文本替换,不进行类型检查,可能导致难以调试的错误。inline 函数提供了类型安全和调试支持,是宏函数的现代替代品。
  4. Debug模式下的 inline

    • 在Debug模式下,为了便于调试,编译器可能会选择不内联展开函数。如果需要在Debug模式下进行内联展开,可能需要在编译器设置中明确启用。
  5. 声明与定义的一致性

    • 对于 inline 函数,建议将声明和定义放在同一个文件中,以避免链接时的地址不一致问题。如果声明和定义分离,可能会导致链接器找不到函数定义的地址,从而引发链接错误。
    • 内联函数会在调用的地方进行展开,那么他就不是一个函数,也就是不会建立函数栈帧,没有函数的地址,那么我就可以在不同的源文件定义,函数名相同,实现不同的内联函数,标准的时候是直接在源文件进行展开,所以就没有链接报错的过程,因为我是直接展开的。

内联函数的使用(不一定非要加上inline)

  1. 类内定义的成员函数:如果一个成员函数的定义位于类定义的内部,即使没有使用 inline 关键字,编译器通常也会尝试将其作为内联函数处理。

  2. 模板函数:模板函数在某些编译器中默认会被当作内联函数处理,因为它们在编译时需要具体化,这与内联展开的过程相似。

  3. 编译器的自动内联:一些编译器可能会根据其优化策略自动决定内联某些没有显式 inline 关键字的函数,尤其是那些短小且调用频繁的函数。

  4. 编译器特定的扩展:某些编译器可能提供了它们自己的内联函数扩展,这些扩展可能不要求使用 inline 关键字。

  5. 将函数定义放在头文件中,并加上 inline 关键字,是创建内联函数的常见做法。这种做法有两个主要目的:

实现1:(这里是放到了类里面,也就是加不加inline其实都是内联函数)

这里的void print();就是内联函数

//.h
//类
class Myclass
{
public:
	//构造函数(进行初始化)
	Myclass(int a = 1, int b = 2, int c = 3)// 缺省参数(全缺省)
	{
		_a = a;
		_b = b;
		_c = c;
	}
	//析构函数(进行释放空间)(没有资源不进行释放)
	//~Myclass();

	//内联函数(inline)(不需要多次调用,直接放到类里面),此时就变成内联函数
	inline void print()
	{
		cout << _a << "/" << _b << "/" << _c << endl;
	}
private:
	int _a;
	int _b;
	int _c;
};

//.cpp
int main()
{
	// 缺省参数(全缺省),包括全缺省,半缺省,无参数缺省参数
	//cout << Myclass::Myclass << endl;
	Myclass m1;//构造初始化之后,
	m1.print();//直接进行打印
    return 0;
}

实现2:

//.h文件
//内联函数
inline void _print()
{
	cout << "内联函数" << endl;
}

//。cpp文件
int main()
{
    _print();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2136928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty笔记05-组件Handler Pipeline

文章目录 概述ChannelHandler方法 ChannelPipeline特点 总结 代码示例服务器端客户端 EmbeddedChannelEmbeddedChannel 的方法 概述 ChannelHandler ChannelHandler 是 Netty 中的一个接口&#xff0c;它定义了处理 I/O 事件的方法。ChannelHandler 可以处理各种类型的事件&a…

ESP01的AT指令连接到阿里云平台

物联网平台提供安全可靠的设备连接通信能力&#xff0c;支持设备数据采集上云&#xff0c;规则引擎流转数据和云端数据下发设备端。此外&#xff0c;也提供方便快捷的设备管理能力&#xff0c;支持物模型定义&#xff0c;数据结构化存储&#xff0c;和远程调试、监控、运维。总…

C++学习笔记之引用(基础)

C学习笔记之引用 https://www.runoob.com/cplusplus/cpp-references.html 引用变量是一个别名&#xff0c;它是已存在变量的另一个名字 一旦把引用初始化为某个变量&#xff0c;可以使用该引用名称或变量名称来指向变量 1、引用vs指针 引用和指针之间有一些相似&#xff0c;也…

计算机的错误计算(九十三)

摘要 探讨 log(y,x) 即以 x 为底 y 的对数的计算精度问题。 Log(y,x)运算是指 x 为底 y 的对数。 例1. 计算 log(123667.888, 0.999999999999999) . 不妨在Python中计算&#xff0c;则有&#xff1a; 若在 Excel 单元格中计算&#xff0c;则有几乎同样的输出&#xff1a; 然…

树莓派交叉编译

目录 一、交叉编译的认知 1.1 本地编译&#xff1a; 1.2 交叉编译是什么&#xff1a; 1.3 为什么要交叉编译&#xff1a; 1.4 什么是宿主机&#xff1f;什么是目标机&#xff1f; 1.5 如何进行交叉编译&#xff1a; 二、交叉编译工具链的安装 2.1 下载交叉编译工具&…

CesiumJS+SuperMap3D.js混用实现可视域分析 S3M图层加载 裁剪区域绘制

版本简介&#xff1a; cesium&#xff1a;1.99&#xff1b;Supermap3D&#xff1a;SuperMap iClient JavaScript 11i(2023)&#xff1b; 官方下载文档链家&#xff1a;SuperMap技术资源中心|为您提供全面的在线技术服务 示例参考&#xff1a;support.supermap.com.cn:8090/w…

设置 AutoCAD双击 DWG 文件时启动新的程序

1 问题描述 原CAD打开多个文件时&#xff0c;会在该程序打开新的标签&#xff0c;合并显示。 有时想打开新文件时启动新的程序&#xff0c;单独显示&#xff0c;如下&#xff1a; 2 解决办法 2.1 方法1 SDI变量可以将CAD设置成单文档模式&#xff0c;设置为1的时候就能实…

音视频直播应用场景探讨之RTMP推流还是GB28181接入?

技术背景 好多开发者跟我们沟通音视频解决方案的时候&#xff0c;不清楚什么时候用RTMP推送模块&#xff0c;什么时候用GB28181设备接入模块&#xff0c;也不清楚二者差异化。实际上&#xff0c;RTMP推流和GB28181接入模块&#xff0c;在很多方面存在差异&#xff0c;如应用领…

IPC之AIDL从认识到实战

目录 前言 什么是AIDL? 为什么要设计出这样一种语言&#xff1f;它能帮助我们干什么&#xff1f; 还有其他方法能实现跨进程通信吗&#xff1f;相较于别的方法AIDL有什么优势呢&#xff1f; AIDL的相关语法 Java与AIDL的不同之处 AIDL默认支持的数据类型&#xff1a; …

怎么浏览URL的PDF文件呢

最近发现PDF文件网页端打开就是丑&#xff0c;不知道怎么办 1. 看着实在不舒服&#xff0c;用chorm的插件 然后原本本地用的也是2345pdf阅读器 2. 之后也下载了adobe pdf的桌面阅读器 2345打开是这个样子 这个是现在啦 如果要一些安装包什么的&#xff0c;评论见~ 最…

相机光学(三十八)——VCM(Voice Coil Motor)音圈马达

VCM&#xff08;Voice Coil Motor&#xff09;音圈马达 0.参考链接1.什么是音圈马达2.对焦&#xff08;变焦&#xff09;原理3.音圈马达结构4.音圈马达工作原理5.VCM 主要性能指标 0.参考链接 &#xff08;1&#xff09;Camera 模组之 VCM篇 &#xff08;2&#xff09;VCM基本…

08 vue3之认识bem架构及less sass 和scoped

bem架构 他是一种css架构 oocss 实现的一种 &#xff08;面向对象css&#xff09; &#xff0c;BEM实际上是block、element、modifier的缩写&#xff0c;分别为块层、元素层、修饰符层&#xff0c;element UI 也使用的是这种架构 1. BEM架构 1. 介绍 1. BEM是Block Element M…

PowerBI 关于FILTERS函数和VALUES函数

本人是powerbi新手&#xff0c;最近在使用Filters()函数和Values()函数时&#xff0c;有点不太明白它们之间的区别&#xff0c;u有时它们得到的结果是一样的&#xff0c;有时却不一样。 官方文档里&#xff0c;Filters()是表示返回直接作为筛选器应用到 columnName 的值 FILT…

MinIO - macOS上配置、Python调用

文章目录 安装配置 MinIO 服务Python 调用SDK 简介调用示例 安装配置 MinIO 服务 1、使用 brew 安装 MinIO 如果您之前使用 brew install minio 安装了MinIO服务器&#xff0c;那么我们建议您改为从 minio/stable/minio 重新安装。 brew install minio/stable/minio2、创建文…

YOLOv5/v8 + 双目相机测距

yolov5/v8双目相机测距的代码&#xff0c;需要相机标定 可以训练自己的模型并检测测距&#xff0c;都是python代码 已多次实验&#xff0c;代码无报错。 非常适合做类似的双目课题&#xff01; 相机用的是汇博视捷的双目相机&#xff0c;具体型号见下图。 用的yolov5是6.1版本的…

Spring Boot集成Akka remoting快速入门Demo

1.什么是Akka remoting&#xff1f; Akka-Remoting一种ActorSystem之间Actor对Actor点对点的沟通协议.通过Akka-Remoting来实现一个ActorSystem中的一个Actor与另一个ActorSystem中的另一个Actor之间的沟通 Akka Remoting限制&#xff1a; 不支持NAT&#xff08;Network Add…

使用Java实现一个简单的B树

1.B树简介 B树是一个搜索树&#xff0c;数据结构可以抽象成如二叉树一样的树&#xff0c;不过它有平衡、有序、多路的特点。 平衡&#xff1a;所有叶子节点都在同一层。有序&#xff1a;任一元素的左子树都小于它&#xff0c;右子树都大于它。多路&#xff1a;B树的每个节点最多…

深入链表的遍历——快慢指针算法(LeetCode——876题)

今天我们一起来学习一下一个快速遍历链表的方法 我们先来看看一道经典的需要遍历链表的题目 &#xff08;题目来自LeetCode&#xff09; 876. 链表的中间结点https://leetcode.cn/problems/middle-of-the-linked-list/ 给你单链表的头结点 head &#xff0c;请你找出并返回链…

C++多态 学习

目录 一、多态的概念 二、多态的实现 三、纯虚函数和多态类 四、多态的原理 一、多态的概念 多态&#xff1a;多态分为编译时多态(静态多态)和运行时多态(动态多态)。编译时多态主要是我们之前学过的函数重载和函数模板&#xff0c;他们在传不同类型的参数就可以调用不同的函…

diff 命令:文本比较

一、diff 命令简介 ​diff ​命令是一个用于比较两个文件并输出它们之间差异的工具。它是文件比较的基本工具&#xff0c;广泛用于源代码管理、脚本编写和日常的文件维护工作中。 ‍ 二、diff 命令参数 diff [选项] 文件1 文件2选项&#xff1a; ​-b​ 或 --ignore-space…