这是一篇被重写的博客,重写参考书籍《C++ Primer Plus》
前言
在C语言中,我们使用预处理语句#define来提供如下的函数形式的宏(内联的原始实现)
#define SQUARE(X) X*X
我们在使用这种宏的时候,就感觉像在使用函数一样,但其实这只是一种文本替换,它并不提供类型检查,而且有时候替换出来的效果和我们想要的不太一样。如下所示
a = SQUARE(5.0); is replaced by a = 5.0*5.0;
b = SQUARE(4.7 + 7.5); is replaced by b = 4.5 + 7.5*7.5 + 7.5;
d = SQUARE(c++); is replaced by d = c++*c++
上面的示例只有一个能正常工作。
C++采用一种更好的方式来实现这种效果(可以将函数在被调用出直接展开,同时可以提供类型检查),那就是内联函数,我们下面会仔细讲解内联函数的使用方式及其注意点。
内联函数
内联函数inline:引入内联函数的目的是为了解决程序中函数调用的效率问题,这么说吧,程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.,这其实就是以空间代价换时间。在使用内联函数时要留神:
使用方法
如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果函数过长(到底多长算长,这个不一定),编译器会忽略 inline 限定符。在类定义中定义的函数都是内联函数,即使没有使用 inline 说明符。使用示例如下。
inline double square(double x){return x}
注意点
1.在内联函数内不允许使用循环语句和开关语句;
2.内联函数的定义必须出现在内联函数第一次调用之前;
3.类结构中所在的类说明内部定义的函数是内联函数。
4.内联函数一般都是1-10行的小函数
有些函数即使声明为内联的也不一定会被编译器内联, 这点很重要; 比如虚函数和递归函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数.(递归调用堆栈的展开并不像循环那么简单, 比如递归层数在编译时可能是未知的, 大多数编译器都不支持内联递归函数). 虚函数内联的主要原因则是想把它的函数体放在类定义内, 为了图个方便, 抑或是当作文档描述其行为, 比如精短的存取函数.