宏
介绍内联函数之前,我们先来回忆一下宏
宏的缺点是什么?
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 中被引用