inline函数的使用和理解

inline函数的使用和理解在 C 中 inline 函数是一种比较小巧的函数 将函数声明为 inline 该函数就成为内联函数 内联函数使函数的调用成本大大降低 因为编译器通常会对内联函数进行优化 如果 inline 函数的本体很小 编译器对内联函数的优化会使编译后产生的目标码比不使用内联函数产生的目标码更小 编译器对内联函数一般都是对每一个调用到该内联函数的地方都以函数本体替换 所以也使其执行速率大大提高 但如果

        在C++中,inline函数是一种比较小巧的函数。将函数声明为inline,该函数就成为内联函数。内联函数使函数的调用成本大大降低,因为编译器通常会对内联函数进行优化,如果inline函数的本体很小,编译器对内联函数的优化会使编译后产生的目标码比不使用内联函数产生的目标码更小,编译器对内联函数一般都是对每一个调用到该内联函数的地方都以函数本体替换,所以也使其执行速率大大提高。但如果使用不得当,大量的本体替换也可能会使最终的目标码很大,这对一台内存有限的嵌入式机器来说,反而会有相反的结果,所以合理的理解并使用inline函数是很有必要的。

        1、inline函数经常可以用来替换一些形似函数的宏,如:

//以a和b较大的值调用func函数 #define CALLMAX(a, b) func((a) > (b) ? (a) : (b))

        按这个宏的操作方式,如果这样使用:

int a = 5, b = 0; CALLMAX(++a, b); //func(7) -> a = 7, b = 0; CALLMAX(++a, b + 10); //func(10) -> a = 6, b =10

        使用宏的方式,会使a被异常累加,会影响后面对变量a的使用。所以以宏去实现一个形似函数的功能不如使用inline函数替换:

template<typename T> inline void callMax(const T& a, const T& b) { func(a > b ? a : b); }

        除了将这样的宏使用inline替换可以防止参数被更改,且inline函数也是函数,它有作用域一说,可以将其定义为class的private成分,一般来说,宏没有这种功能。

        2、inline的隐式和显式声明:

        inline函数有隐式和显式两种声明方式,隐式的声明方式如这样:

class Animal { public: ... int number() const { return theNum; } //隐式的inline ... private: int theNum; };

        显式声明就是直接在函数定义式前加inline声明,如上面第1条中的程序。

        3、inline函数通常都置于头文件内:

        因为inline函数通常都是编译器将函数本体替换到所调用的地方,所以一般都将inline函数声明到头文件内。但它与template无关,在很多代码中,经常见到使用template声明的接口总是使用inline声明,其实它们是无关联的,在需要inline的时候就是用inline,不需要inline的时候就不要使用inline。

        4、无法被inline的情况:

        如果函数比较复杂,比如内部有循环或递归的函数,或有对virtual函数的调用声明为inline,则编译器无法真正将它inline化。或者,当使用函数指针的方式去调用内联函数时,也是无法真正inline化的:

inline void func() {...} //func为一个声明为inline的函数 void (*pfunc)() = f; //pfunc指向f ... func(); //这种调用可以被inline pfunc(); //这种调用不能够被inline

        5、尽量不要对构造函数和析构函数inline:

        假如有这样的两个继承类:

class Base { public: ... private: std::string bm1, bm2; }; class Derived: public Base { public: Derived() {} //inline,但实现是空的 ... private: std::string dm1, dm2; };

        对继承类Derived的构造函数隐式inline,虽然看起来里面是一个空实现,但实际上,在编译器看来,内部其实被本体替换为(大致代码):

Derived::Derived() { Base::Base(); //继承类构造函数首先先调用其基类的构造函数 try { dm1.std::string::string(); } catch(...) { Base::~Base(); throw; } try { dm2.std::string::string(); } catch(...) { dm1.std::string::~string(); Base::~Base(); throw; } }

        这只是很小的类,如果类很大,内部的声明变量众多,且继承关系复杂,将构造函数inline化,会使代码更加膨胀,有可能会影响性能和速度。所以最好不要对构造和析构函数inline。

        6、不要过多的使用inine函数:

        inline函数的特点使得在过多使用inline函数时,会使代码的可移植性降低。如果func函数是inline函数,那么一旦哪一天改变了func函数的实现方式,那所有用到func函数的地方都需要重新编译。并且,对程序调试而言,大部分inline函数无法调试,所以如果使用过多,代码的可调试性也会降低。所以,一般都是在在小型且调用很频繁的函数身上,将其声明成inline函数,是程序的效率提升上去。这就是inline函数的一般使用原则。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231825.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java中Scanner类用法的详解[通俗易懂]

    java中Scanner类用法的详解[通俗易懂] 一  java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。首先要导入包  import java.util.Scanner;Scanner类的创建对象:   Scanner S=newScanner(System.in);   方法基本格式  hasNextXxx()  判断是否还有下一个输入项,其中Xxx可以是Int,…

    2022年7月7日
    23
  • Seata-Saga模式 原理

    Seata-Saga模式 原理1Saga模式示例1.1Saga状态机工具状态机设计组件:seata-saga-statemachine-designer状态机在线画图工具:saga_designer1.2代码示例github上Seata-sample有完整的示例代码,SeataSaga模式中有此示例的完整介绍和分析。这里仅摘取部分和介绍原理有关的代码进行分析。1.2.1初始化dbmysql示例:CREATETABLEIFNOTEXISTS`seata_state_machine_def`(

    2026年1月26日
    3
  • 计算机总线控制驱动,什么是sm总线控制器,总线控制器驱动怎么安装?「建议收藏」

    计算机总线控制驱动,什么是sm总线控制器,总线控制器驱动怎么安装?「建议收藏」如果您的设备管理器中”sm总线控制器”有一黄色问号,那么你就可以下载这款Intel主板上的SM总线控制器驱动程序(含64位)来进行安装了!什么是sm总线控制器?sm总线控制器全称是SystemManagementBus,是主板控制芯片上的一个通信控制器,sm总线控制器的概念是由Intel提出并应用的,使用sm总线控制器可以提升主板的使用效率。说白了,sm总线控制器是主板驱动的一部分,如果你的设…

    2022年5月3日
    171
  • 如何做好Flex与Java交互「建议收藏」

    如何做好Flex与Java交互「建议收藏」三种flex4与Java顺利通信的方式是:flex与普通java类通信RemoteObject;flex与服务器交互HTTPService;flex与webservice交互WebService

    2022年7月2日
    23
  • 从CentOS官网下载系统镜像详细教程[通俗易懂]

    从CentOS官网下载系统镜像详细教程[通俗易懂]1、CentoS简介    CentOS(CommunityEnterpriseOperatingSystem,社区企业操作系统)是一个基于RedHatLinux提供的可自由使用源代码的企业级Linux发行版本,以高效、稳定著称。它使用与RedHat相同的源代码编译而成,而且是开源免费的,因此有些要求高度稳定性的服务器以CentOS替代商业版的RedHatEnterpris…

    2022年5月3日
    65
  • 移动端,PC端,微信等常用平台和浏览器判断

    移动端,PC端,微信等常用平台和浏览器判断移动端,PC端,微信等常用平台和浏览器判断

    2022年4月24日
    57

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号