@[toc](目 录)
一.什么是内联函数
内联函数,故名思意,作用类似函数,那么什么是内联呢?内联的意义就是:程序编译过程中,遇到内联函数时,原地展开内联的代码,这样就省去了正常函数的调用开销,使程序更加的高效
内联函数,写起来像函数,运行起来也像函数(执行一个完整的单元功能),很重要的一点,在某些方面可以代替宏(macro)—至于为什么代替宏要好一些,看官可以移步这里-》》》通常情况下,要用const与inline代替宏,那么为什么不建议用宏呢?
二.内联函数格式
inline 返回类型 f() {..........}; C++支持分离编译,考虑到这一点,我们如果使用一个内联函数的时候,放在.h文件是一个更好的选择,让对这个函数体有需求的其他cpp文件都可以使用
三.内联函数使用的条件
- 代码行数少
- 少了展开也不会很多,少了有助于预防写出太复杂的代码
- 逻辑简单
- 我要是去递归,去循环,去迭代,那我每次都展开,保不齐代码体积就被我涨满了,大水淹了龙王庙,就算存在虚拟内存,内联后有倘若有极大的代码膨胀,也会导致系统颠簸,程序卡顿
- 代码复用率高
- 复用率高,我的便捷才能体现出来啊,要不就一次,有我和没我有屁干系
四.使用内联必须特别知道的point
1. 写了inline,但是不一定运行的时候真的是当内联函数去处理了
在编译时,inline起一个提示编译器的功能,不会强制要求编译器的行为——而且,事实上,编译器很多时候会忽略到这个提示,大多数编译器拒绝去内联“复杂”的函数,最明显的就是,一个包含循环或者递归的函数,一般是不内联成功的(“循环和递归,我展开,那我的代码量增长的也太多了吧,我才不干”编译器如是说道)
2. 虚函数我去内联?
可惜,虚函数内联,可以想想,但是我编译器不会统一的,虚函数,等到运行的时候才确定位置,内联,编译的时候得找到,那么也不难理解编译器拒绝内联虚函数了
- 构造函数,析构函数我去内联
你可以试试,你以为一个默认的构造,写起来是这样的
class Base{
Base() {}
};
inline一下多好,实际上,构造和析构函数,不太适合去内联,因为保不齐你的构造函数或者析构函数内,隐藏着不知多复杂的函数调用。。,比如,一旦存在基础关系,构造之前会调用基类构造。。结果可想而知
4. 一定注意,{“内联”–变成–“外联”}
我们当时为了方便,很开心的将内联函数写入.h的头文件中,那么就有多个有需求的cpp可以访问内联了
!但是,加入我一个cpp文件内内联使用编译器没有通过呢,编译器会生成一个函数,那么我另外一个cpp也如是,生成了一个一样的函数,完蛋,函数重复,报错!
但是你不用担心,我们的前辈也想到了,于是,编译器遇到未被内联的内联函数,就会在使用它的文件内,拷贝一份;拷贝的这一份,功能上,相当于这个cpp文件的一个static 函数
。。。于是你我都傻眼了,每一个cpp都有一个这样的类似static???
答案是对的,也即是说,当内联函数没有被内联,经过多余的拷贝(静态拷贝一份来到cpp),调用的时候开销也是和函数调用一样的
5. 内联展开后是二进制代码,修改后,使用该内联函数的所有程序必须重新编译,在链接,而修改函数,只需要重新链接五.总结若能做到明智地使用,内联函数将是每个 C++程序员百宝箱中的一件无价之宝。当然,它们并不像我们所想象的那样简单和直接。一定要慎重选择,遇到适合内联的函数,一定不要犹豫,同时,当内联不被编译器“内联”时,一定注意编译器的警告!同时也要注意代码体积的问题!
|