Bootstrap

C++ 内联函数 详解分析 (含代码分析)

介绍内联函数之前,我们先来回忆一下宏

宏的缺点是什么?

1. 不方便调试宏。(因为预编译阶段进行了替换)
2. 导致代码可读性差,可维护性差,容易误用。
3. 没有类型安全的检查 。

1.

通过第一个例子可以看出宏的可读性差,在用宏定义函数时很容易误用导致得不到想要的结果,实际第二个想要的结果是18,但由于宏在预处理时完全替换,在定义宏函数时出现错误导致最后误用

2.

另一种宏定义函数解决了第一个例子的问题,但是他安全吗?同样是不正确的,当如图中调用函数时,运算符的优先级不一样,得到的结果是意料之外的。在定义宏函数时即便优化了也可能造成误用。

3.

再更改一次宏函数的定义

此时宏函数的定义才正确,但是经历这几个例子,宏定义在使用时会很容易被误用,那么宏定义最大的缺点是什么?

优点

1. 增强代码的复用性。
2. 提高性能。

C++有哪些技术替代宏

1. 常量定义 换用 const enum
2. 短小函数定义 换用内联函数

内联函数

inline 修饰 的函数叫做内联函数, 编译时 C++ 编译器会在 调用内联函数的地方展开 ,没有函数调
用建立栈帧的开销,内联函数提升程序运行的效率。
内联函数在使用时和宏定义一样没有建立栈帧开销,同时不会犯宏定义可能出现的错误。
内联函数,在编译期间编译器会用函数体替换函数的调用。

1.未使用内联函数,函数调用

2.函数体替换,未调用函数

特性

1. inline 是一种 以空间换时间 的做法,如果编译器将函数当成内联函数处理,在 编译阶段,会
   用函数体替换函数调用
    缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
2. inline 对于编译器而言只是一个建议,不同编译器关于 inline 实现机制可能不同 ,一般建
    议:将 函数规模较小 ( 即函数不是很长,具体没有准确的说法,取决于编译器内部实现 )
    是递归、且频繁调用 的函数采用 inline 修饰,否则编译器会忽略 inline 特性。
    函数太长(超过十行),递归,频繁调用都不建议使用内联函数
3. inline 不建议声明和定义分离,分离会导致链接错误。因为 inline 被展开,就没有函数地址
    了,链接就会找不到
    使用内联函数时声明和定义一定要放一起
//F.h
inline void f(int i);

inline void f(int i)
{
	cout << "f(int i)" << i << endl;
}
// F.h
#include <iostream>
using namespace std;
inline void f(int i);
// F.cpp
#include "F.h"
void f(int i)
{
 cout << i << endl;
}
// main.cpp
#include "F.h"
int main()
{
 f(10);
 return 0;
}
// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl 
//f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用

;