欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

内联函数的深度探究—预处理、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;
}

运行如下: 

内联函数的深度探究—预处理、const、static与sizeof(四)

存疑

经过我的一个小测试,宏也可以跟着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;
}

运行如下: 

内联函数的深度探究—预处理、const、static与sizeof(四)

 

为什么不能将所有函数都定义成内联函数?

利用只有一个,防止开销过大:

  • 如果函数体的代码比较长,会使内联函数的消耗过大
  • 如果出现循环,同样,也会使内联函数的消耗过大
  • 如果把构造函数或者析构函数设置为内联函数的时候,要小心,构造、析构函数会不会有“偷偷”操作的行为,比如,不仅会把当前的构造函数执行一遍,也会把继承的构造函数,也执行一遍,这样的话,也会使开销大大增加!

好在编译器在执行内联函数的时候,会先作检查,能按内联函数那样高效率的完成的就执行,不能的话,就自动转化为普通函数来执行。