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

目录

 

为什么要引入内联函数?

内联函数和宏定义的区别

为什么内联函数可以取代宏定义且比宏好?

相对于宏内联函数独有的使用场景

存疑

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


为什么要引入内联函数?

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;
}

运行如下: 

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

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

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

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

发布了271 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_17846375/article/details/104943213