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

embedded/2024/9/24 10:21:00/

           💓 博客主页:倔强的石头的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.ppmy.cn/embedded/116047.html

相关文章

kotlin—— withTimeoutOrNull的介绍和使用场景

withTimeoutOrNull 是 Kotlin 协程库中的一个非常有用的函数,它允许你在指定的时间内执行一个代码块,如果在指定的时间内代码块没有执行完毕,那么它会返回 null,而不是抛出一个异常。这个函数在处理可能需要较长时间完成的操作&am…

在 macOS 上安装 FFmpeg 的详细指南

FFmpeg 是一个强大的多媒体框架,可以用于录制、转换和流式传输音频和视频。无论你是视频编辑工作者,还是想要处理音频文件,FFmpeg 都是一个不可或缺的工具。本文将介绍在 macOS 上安装 FFmpeg 的几种方法。 方法 1: 使用 Homebrew 安装 FFmp…

【uni-app】小兔鲜项目-基础架构-请求和上传文件拦截器

注意事项 uni.request 请求封装 请求和上传文件拦截器 uniapp 拦截器: uni.addInterceptor 接口说明:接口文档 实现需求 拼接基础地址设置超时时间添加请求头标识添加 token 参考代码 // src/utils/http.ts// 请求基地址 const baseURL https://pca…

provide,inject父传子

这个方法传递子参数,可以让所有的子组件获取到,不能子组件传递给父组件 父组件 说下大概思路,导入privode,然后使用privode方法,有点像redis,key value形式存值,子组件可以通过key来获取你要传…

计算机毕业设计之:基于微信小程序的中药材科普系统(源码+文档+讲解)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

Redis数据结构之哈希表

这里的哈希表说的是value的类型是哈希表 一.相关命令 1.hset key field value 一次可以设置多个 返回值是设置成功的个数 注意,哈希表中的键值对,键是唯一的而值可以重复 所以有下面的结果: key中原来已经有了f1,所以再使用hse…

计算机科学(学习笔记四)

早期的编程方式 纸片打孔等方法 汇编语言 编程语言发展史 汇编语言也叫机器语言,是计算机的母语。但01不便于人们操作,人们为了方便操作,会输入文字指令,通过汇编器自动转成二进制指令。 但汇编码和底层硬件仍息息相关&#xff…

网安新声 | 黎巴嫩BP机爆炸事件带来的安全新挑战与反思

网安加社区【网安新声】栏目,汇聚网络安全领域的权威专家与资深学者,紧跟当下热点安全事件、剖析前沿技术动态及政策导向,以专业视野和前瞻洞察,引领行业共同探讨并应对新挑战的策略与可行路径。 9月17日,黎巴嫩境内发…