【C++指南】inline内联函数详解

           💓 博客主页:倔强的石头的CSDN主页 

           📝Gitee主页:倔强的石头的gitee主页

            ⏩ 文章专栏:《C++指南》

                                  期待您的关注

1b7335aca73b41609b7f05d1d366f476.gif

目录

引言

C++为什么引入了inline来替代C语言中的宏

inline的基本用法

定义inline函数

inline的优势与限制

优势

限制

inline的注意事项

结论


引言

  • 在C++编程中,inline关键字是一个非常重要的特性——它用于向编译器提供建议,以优化函数的调用方式。
  • 通过将函数定义为inline,编译器可以尝试将函数的代码直接插入到每个调用点,而不是通过常规的函数调用来执行。
  • 这种优化方式可以减少函数调用的开销,提高程序的执行效率。然而,inline关键字的使用并非没有限制,本文将详细介绍inline的关键特性、使用方法、优势以及潜在的缺点。

 

C++为什么引入了inline来替代C语言中的宏

C语言实现宏函数也会在预处理时替换展开,可以提高程序的执行效率,但是宏函数实现很复杂很容易出错的,且不方便调试,C++设计了inline目的就是替代C的宏函数。

// 实现⼀个ADD宏函数的常⻅问题
//#define ADD(int a, int b) return a + b;
//#define ADD(a, b) a + b;
//#define ADD(a, b) (a + b)

C++的inline与C中的宏进行对比:

  1. 类型安全
    • 宏定义是在预处理阶段进行文本替换,不进行类型检查。这可能导致类型不匹配的错误,尤其是在复杂的宏定义中。
    • inline函数是真正的函数,会在编译时进行类型检查,从而提高了代码的安全性和可维护性。
  2. 调试方便
    • 由于宏定义只是简单的文本替换,调试时很难看到宏展开后的代码,这增加了调试的难度。
    • inline函数则可以在调试器中看到,就像普通函数一样,可以单步执行,查看变量值等,大大方便了调试过程。
  3. 作用域和链接性
    • 宏定义没有作用域的概念,一旦定义,在定义点之后的文件中都可以使用,这可能导致命名冲突。
    • inline函数具有和普通函数相同的作用域和链接性,可以很好地控制其可见性和使用范围。
  4. 参数处理
    • 宏定义在参数处理上可能不够灵活,特别是当参数有副作用时(如递增、递减操作),宏展开后可能导致意外的行为。
    • inline函数作为真正的函数,可以正确处理参数,包括参数的传递和返回,避免了宏定义中可能出现的问题。

 

inline的基本用法

定义inline函数

在C++中,将函数定义为inline的方法很简单,只需在函数声明或定义前加上inline关键字。例如:

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

对于类的成员函数,如果在类内部定义(即直接在类体中实现),则该函数默认为inline候选,无需显式添加inline关键字。但若在类外部定义成员函数,则需显式添加inline关键字:

 

class MyClass {  
public:  inline int getValue() const { // 可以在这里显式声明为inline,也可以省略  return m_value;  }  private:  int m_value;  
};  // 在类外部定义时,需要显式添加inline关键字  
inline int MyClass::getValue() const {  return m_value;  
}
inline的作用
  1. 减少函数调用开销:通过内联函数,可以避免函数调用的额外开销,如保存和恢复现场、传递参数等。
  2. 提高程序执行速度:由于内联函数的代码会被插入到调用处,可以减少函数调用的时间,从而提高程序的执行速度。
  3. 优化代码组织inline函数通常定义在头文件中,这样编译器在处理源文件时可以直接看到函数的定义,有助于优化。

inline的优势与限制

优势

  1. 提高执行效率通过减少函数调用的开销,内联函数可以显著提高程序的执行效率,尤其是对于短小且频繁调用的函数
  2. 类型安全:与宏定义相比,内联函数是真正的函数,具有类型安全检查,可以避免因类型不匹配导致的错误。
  3. 作用域明确:内联函数具有明确的作用域,而宏定义则是全局的,容易引发命名冲突。

限制

  1. 代码膨胀如果内联函数的代码较大或调用频繁,将函数体插入到每个调用点会导致代码体积显著增加,可能降低指令缓存的效率,反而影响性能
  2. 编译时间增加:内联函数可能导致编译时间增加,因为编译器需要处理更多的代码。
  3. 编译器优化选择inline只是对编译器的建议,编译器会根据函数的大小、调用频率以及自身的优化策略来决定是否进行内联。不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。

inline的注意事项

  1. 不要滥用通常只将小型、频繁调用的函数标记为inline,以避免代码膨胀和编译时间增加
  2. 避免在构造函数和析构函数中使用:这些函数往往包含大量的隐式代码,如果内联了这些函数,很容易导致代码膨胀。
  3. 注意函数体的大小:对于复杂的函数,内联可能不会带来性能提升,反而可能导致代码膨胀。

结论

inline关键字是C++中一个强大的特性,它允许开发者向编译器提出内联函数的建议,以优化程序的执行效率。然而,使用inline时需要注意其优势和限制,避免滥用导致的问题。正确地使用inline,可以在提高程序性能的同时,保持代码的可读性和可维护性。

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IO模型---BIO、NIO、IO多路复用、AIO详解

本篇将想给详细解释一下什么是BIO、NIO、IO多路复用以及AIO~ 同步的阻塞(BIO)和非阻塞(NIO)的区别 BIO:线程发来IO请求后,一直阻塞着IO线程,需要缓冲区这边数据准备好之后,才会进行下一步的操作。 举个🌰&#xff1…

HarmonyOS应用开发者基础认证

目录 一、判断二、单选三、多选 一、判断 1、HarmonyOS提供了基础的应用加固安全能力,包括混淆、加密和代码签名能力。正确 2、可以通过ohpm uninstall 指令下载指定的三方库。错误 3、支持模块化开发是指一个应用通常会包含多种功能,将不同的功能特性…

【读书笔记-《30天自制操作系统》-23】Day24

本篇内容依然比较简单,主要是优化窗口功能以及开发定时器应用程序。首先是优化窗口的切换功能,实现通过键盘和鼠标切换窗口,然后是实现通过鼠标关闭窗口。接着实现不同窗口输入状态的切换,最后是实现定时器的API与应用程序。 1.…

Windows Server2016多用户登录破解

使用场景 很多时候,公司开发和测试运维会同时登录同一台windows服务器进行查询、更新、维护等操作,本文就来介绍一下Windows2016配置多人远程桌面登录实现,感兴趣的可以了解一下。 操作流程 (1)首先桌面需要安装远程…

旅行社区应该如何规划?

近年来,旅游行业逐渐恢复,包括微度假、精致露营、康养旅游、乡村民宿等旅游模式。用户旅游支出、旅游人次逐渐恢复,旅游收入仍待提升。 那么旅游社区应该如何搭建,内容如何规划呢? 我们了解到,很多旅游网…

kettle 数据库迁移 使用分页原理实现 数据库mysql

使用 kettle 9.0 先修改配置文件: C:\Users\xx\.kettle 新增如下配置,解决mysql 空字符串 自动转 null bug KETTLE_EMPTY_STRING_DIFFERS_FROM_NULLY git地址: GitHub - 2292011451/kettle_tool 第一步: 先把要迁移的表进行读取,循环查询每个表的最大数量以及页数,追加到…

ROS 设置dhcp option 6 多个地址格式

ROS routeOS 手工设置 dhcp 服务 option 6 多个dns 地址格式。字符串方式

机器学习(西瓜书)第 14 章 概率图模型

14.1 隐马尔可夫模型 机器学习最重要的任务,是根据一些已观察到的证据(例如训练样本)来对感兴趣的未知变量(例如类别标记)进行估计和推测。概率模型(probabilistic model)提供了一种描述框架&a…

动态线程池(四)

动态线程池 dtp生命周期管理 生命周期相关类图 DtpExecutor EagerEtpExecutor OrderedDtpExecutor TaskWrapper任务包装器 MdcRunnable TaskWrappers NotifyEnum NoticeManager通知管理器 InvokerChain调用链

【CPP】类与继承

14 类与继承 在前面我们提到过继承的一些概念,现在我们来回顾一下 打个比方:在CS2中我们把玩家定义为一个类 class 玩家: 血量:100阵营(未分配)服饰(未分配)位置(未分配)武器(未分配)是否允许携带C4(未分配)是否拥有C4(未分配) 当对局创建时,会新生成两个类,这两个类继承自&qu…

JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)

大家好,今天我要分享的是如何在树形结构的数据中,根据特定条件设置节点及其所有子节点的显示属性。在实际项目中,这种需求非常常见,特别是在需要动态展示和隐藏节点的情况下。下面我将通过一个具体的示例来讲解实现过程。 需求分析…

有关C# .NET Core 过滤器的使用

想用一个过滤器实现特定接口的审核日志记录,结果报了错,看了看感觉有些基础要补,所以想记录下来 错误: 在属性过滤器中使用了依赖注入,结果在应用在控制层接口时报了传参的错 //过滤器 public class AuditRecordFil…

tcpdump使用方法

一、centos上可以采用下面的命令进行安装。 yum install tcpdump 二、实例: 1、监视指定网络接口的数据包 即监听指定网卡的数据包,若不指定网卡,默认tcpdump只会监视第一个网络接口。如监听 eth0网卡,如下: tcpd…

Double-Fetch漏洞检测工具的部署、使用与原理分析

文章目录 前言1、概述1.1、简介1.2、工作原理1.2.1、内核空间与用户空间的信息传递1.2.2、Double-Fetch漏洞产生的原因1.2.3、产生Double-Fetch漏洞的情况1.2.4、一个Double-Fetch漏洞示例1.2.5、Double-Fetch漏洞检测工具原理 1.3、模式匹配原理分析1.3.1、Coccinelle介绍1.3.…

大厂程序员的健身之路

大厂程序员的健身之路 基本信息饮食正餐营养补剂 睡眠训练计划 基本信息 健身时间:2023.03 -> 2024.09体重变化:52kg -> 67kg 饮食 正餐 早餐:不吃午餐:两碗米饭 鱼/鸡肉 蔬菜 酸奶晚餐:两碗米饭 鱼/鸡肉…

java之杨辉三角问题

给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 如何实现呢? 思路:首先,我们可以将杨辉三角视作i行j列的二维数组。除了第一行和第二行之外&am…

BuripSuiteProfessional 抓取HTTPS配置

1.电脑拿开代理 谷歌为例 点击三点-设置 -输入代理--点击代理设置 打开手动代理---IP ,端口如图-点击保存 2.下载CA证书 打开代理后,谷歌浏览器打开,输入/burp--如下图-点击CA证书下载证书 选择下载目录--桌面 3.安装CA证书 谷歌浏览器中点开设置-输入证书-点击安全 点击…

传知代码-多示例AI模型实现病理图像分类

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 本文将基于多示例深度学习EPLA模型实现对乳腺癌数据集BreaKHis_v1的分类。EPLA模型是处理组织病理学图像的经典之作。EPLA模型是基于多示例学习来进行了,那么多示例学习模型对处理病理学图像具有…

优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序

遗传算法(Genetic Algorithm, GA)是一种启发式搜索算法,用于寻找复杂优化问题的近似解。它模拟了自然选择和遗传学中的进化过程,主要用于解决那些传统算法难以处理的问题。 遗传算法的基本步骤: 初始化种群&#xff0…

GNN-RAG:用于大模型推理的图神经检索

GNN-RAG:用于大模型推理的图神经检索 秒懂大纲提出背景解法拆解全流程优化创意总结 论文:GNN-RAG: Graph Neural Retrieval for Large Language Model Reasoning 代码:https://github.com/cmavro/GNN-RAG 秒懂大纲 ├── GNN-RAG【主题】…