内联函数的深度探究—预处理、const、static与sizeof(四)
程序员文章站
2024-01-30 11:28:35
...
目录
为什么要引入内联函数?
inline函数推出的目的,是为了弥补宏定义的缺点,同时又能很好的继承宏的优点。用内联函数替代宏定义,来解决程序中函数调用的效率问题。
内联函数和宏定义的区别
- 内联函数是再编译时展开的,宏是在预编译时展开的。
- 在编译的时候,内联函数是直接镶嵌到目标代码中的,而宏只是一个简单的文本替换。
- 宏不是函数,但内联函数是函数。
- 内联函数因为自身是函数,可以完成诸如,类型检测,语句是否正确等编译功能,但宏不行,宏只能机械的进行替换。
- 宏没有内联函数稳定,容易出现二义性的歧义
为什么内联函数可以取代宏定义且比宏好?
- 内联函数和宏一样,都可以直接将定义的部分放入目标代码中去,没有调用的开销,效率都很高
- 类的内联函数,是个函数,编译器在调用它的时候,会去检测内联函数的参数类型、语句是否正确等状况,消除了调用报错的风险,而这些是宏没有的。
- 内联函数既然是函数,那么,可以准确的使用类的成员对象,而宏不可以(因为宏无法将this指针放在合适的位置)。
相对于宏内联函数独有的使用场景
内联函数既然是函数,那么,可以准确的使用类的成员对象,而宏不可以(因为宏无法将this指针放在合适的位置)。
比如如下的,用内联函数可以调用类的私有保护成员:
#include <stdio.h>
#include <iostream>
class test
{
public:
void setnum(int num);
private:
int num;
};
inline void test::setnum(int i)
{
printf("i=%d\n",i);
}
int main()
{
test A;
A.setnum(5);
system("pause");
return 0;
}
运行如下:
存疑
经过我的一个小测试,宏也可以跟着this进行更改啊!
#include <stdio.h>
#include <iostream>
#define Pr(i) num = i
class test
{
public:
void sets(int i)
{
Pr(i);
}
void prsets()
{
printf("%d\n", num);
}
private:
int num;
};
int main()
{
test A,B;
A.sets(5);
A.prsets();
B.sets(3);
B.prsets();
A.prsets();
system("pause");
return 0;
}
运行如下:
为什么不能将所有函数都定义成内联函数?
利用只有一个,防止开销过大:
- 如果函数体的代码比较长,会使内联函数的消耗过大
- 如果出现循环,同样,也会使内联函数的消耗过大
- 如果把构造函数或者析构函数设置为内联函数的时候,要小心,构造、析构函数会不会有“偷偷”操作的行为,比如,不仅会把当前的构造函数执行一遍,也会把继承的构造函数,也执行一遍,这样的话,也会使开销大大增加!
好在编译器在执行内联函数的时候,会先作检查,能按内联函数那样高效率的完成的就执行,不能的话,就自动转化为普通函数来执行。