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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • layui弹出层使用「建议收藏」

    layui弹出层使用「建议收藏」一直在用的一个提示层,现在分享给大家,感谢作者贤心//首先引入js文件<scriptsrc=”./layer.js”></script>常用的//提示层layer.msg(‘玩命提示中’)提示后可以继续操作的,这种会显示和拒绝差不多//提示层layer.msg(‘玩命卖萌中’,function(){//关闭后的操作//l…

    2022年6月9日
    31
  • 了解ACL—通配符掩码「建议收藏」

    了解ACL—通配符掩码「建议收藏」学习ACL,搞懂ACL就不能不搞定wildcardmask,通配符掩码。说简单点,通配符掩码就是0为绝对匹配,必须严格匹配才行,而1为任意,从某种意义上讲,如果一个8位上有一个1字符,那也只有两种方式,0或者1,但是如果进行组合,那么方式就多了。举例说明吧。一般我们在应用上都是进行地址块的匹配,怎么讲呢?就是说:1)对某个ABC类网进行匹配或者教通配符屏蔽2)对某个子网应用ACL。…

    2022年7月19日
    9
  • 什么是软连接,软连接的作用[通俗易懂]

    什么是软连接,软连接的作用[通俗易懂]什么是软连接,其实就是别名,简单的理解就是相当于windows的快捷方式。ln-s/opt/dir/tmp/ddd命令行格式如下:ln-s源目录目标软连接进入软连接cd/opt/dir实际上ddd这个软连接就相当于/opt/dir了…

    2022年9月30日
    3
  • SqlServer中Exists的使用

    SqlServer中Exists的使用1、简介不相关子查询:子查询的查询条件不依赖于父查询的称为不相关子查询 相关子查询:子查询的查询条件依赖于外层父查询的某个属性值的称为相关子查询。带Exists的子查询就是相关子查询 Exists表示存在量词:带有Exists的子查询不返回任何记录的数据,只返回逻辑值“True”或“False”2、表结构选课表:学号StudentNo、课程号CourseNo学生表:学号Stude…

    2022年7月14日
    61
  • 物联网架构在现有互联网_物联网行业发展现状及整体体系结构

    物联网架构在现有互联网_物联网行业发展现状及整体体系结构1.说明  这一小节,也不具体讲些什么了。最近一个半月都在摸鱼,没什么事做,慢慢学习着SpringBoot和SpringCloud。下面两张图是进行的一次小结。以后随着深入,整个架构肯定是会变的。现在记录一下,每个项目成长都是有一个过程的。…

    2022年9月18日
    5
  • 身为三本的我就是凭借这些前端面试题拿到百度京东offer的,前端面试题2021及答案「建议收藏」

    点进来之后你的噩梦就要来了,接下来你要面对上百道面试题,那么,如果你——是个小白菜:推荐使用2~3周的时间来消化接下来的面试题,遇到不会的专业名词请立刻去搜;文章中只是简答,如果想要详细了解的话还需要你自觉去搜索如果你是个大神:好叭先给您拜个早年,大哥大嫂过年好。请温柔点黑我。顺便,如果有错误的地方请各位一定要指出,免得误导更多人。接下来的题我会根据重点程度使用⭐来标记,⭐越多标明越重点,满星是5颗星ok,你准备好了吗?咱们开始吧!JS数据类型面试官:JavaSc

    2022年4月7日
    34

发表回复

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

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