C++ inline内联函数

个人主页:Jason_from_China-CSDN博客

所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客

所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客

概念概述

  • 用 inline 修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立栈帧了,就可以提高效率。展开的意思就是不建立栈帧了,直接进行执行,所以本质就是提升效率用的
  • inline 对于编译器而言只是一个建议,也就是说,你加了 inline 编译器也可以选择在调用的地方不展开,不同编译器关于 inline 什么情况展开各不相同,因为C++标准没有规定这个。inline 适用于频繁调用的短小函数,对于递归函数,代码相对多一些的函数,加上 inline 也会被编译器忽略。
  • C语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不方便调试,C++设计了 inline 目的就是为了替代C的宏函数。
  • VS编译器 debug版本下面默认是不展开 inline 的,这样方便调试,debug版本想展开需要设置一下以下两个地方。
  • inline 不建议声明和定义分离到两个文件(所以往往直接定义在头文件),分离会导致链接错误。因为 inline 被展开,就没有函数地址,链接时会出现报错。

补充说明

  1. 内联展开与栈帧

    • 内联函数的展开并不意味着完全不建立栈帧,而是减少了函数调用的额外开销。如果内联函数中涉及复杂的操作,如循环或条件分支,编译器可能会决定不进行内联展开,或者在某些情况下,内联展开可能仍然需要栈帧来保存局部变量和寄存器。
  2. 编译器的 inline 决策

    • 编译器会根据函数的大小、复杂度、调用频率以及优化级别等因素来决定是否进行内联展开。通常,小而简单的函数更可能被内联展开。(也就是如果内联的复杂度过高,会直接展开内联)。
    • 展开内联函数并不意味着函数的代码会被移动到实现文件(.cpp文件)中。实际上,内联函数的定义通常位于头文件(.h或.hpp文件)中,这样编译器在处理每个包含该头文件的源文件时,都能够看到函数的定义,并在每个调用点进行展开。
  3. 宏函数与 inline

    • 宏函数在预处理器阶段进行文本替换,不进行类型检查,可能导致难以调试的错误。inline 函数提供了类型安全和调试支持,是宏函数的现代替代品。
  4. Debug模式下的 inline

    • 在Debug模式下,为了便于调试,编译器可能会选择不内联展开函数。如果需要在Debug模式下进行内联展开,可能需要在编译器设置中明确启用。
  5. 声明与定义的一致性

    • 对于 inline 函数,建议将声明和定义放在同一个文件中,以避免链接时的地址不一致问题。如果声明和定义分离,可能会导致链接器找不到函数定义的地址,从而引发链接错误。
    • 内联函数会在调用的地方进行展开,那么他就不是一个函数,也就是不会建立函数栈帧,没有函数的地址,那么我就可以在不同的源文件定义,函数名相同,实现不同的内联函数,标准的时候是直接在源文件进行展开,所以就没有链接报错的过程,因为我是直接展开的。

内联函数的使用(不一定非要加上inline)

  1. 类内定义的成员函数:如果一个成员函数的定义位于类定义的内部,即使没有使用 inline 关键字,编译器通常也会尝试将其作为内联函数处理。

  2. 模板函数:模板函数在某些编译器中默认会被当作内联函数处理,因为它们在编译时需要具体化,这与内联展开的过程相似。

  3. 编译器的自动内联:一些编译器可能会根据其优化策略自动决定内联某些没有显式 inline 关键字的函数,尤其是那些短小且调用频繁的函数。

  4. 编译器特定的扩展:某些编译器可能提供了它们自己的内联函数扩展,这些扩展可能不要求使用 inline 关键字。

  5. 将函数定义放在头文件中,并加上 inline 关键字,是创建内联函数的常见做法。这种做法有两个主要目的:

实现1:(这里是放到了类里面,也就是加不加inline其实都是内联函数)

这里的void print();就是内联函数

//.h
//类
class Myclass
{
public:
	//构造函数(进行初始化)
	Myclass(int a = 1, int b = 2, int c = 3)// 缺省参数(全缺省)
	{
		_a = a;
		_b = b;
		_c = c;
	}
	//析构函数(进行释放空间)(没有资源不进行释放)
	//~Myclass();

	//内联函数(inline)(不需要多次调用,直接放到类里面),此时就变成内联函数
	inline void print()
	{
		cout << _a << "/" << _b << "/" << _c << endl;
	}
private:
	int _a;
	int _b;
	int _c;
};

//.cpp
int main()
{
	// 缺省参数(全缺省),包括全缺省,半缺省,无参数缺省参数
	//cout << Myclass::Myclass << endl;
	Myclass m1;//构造初始化之后,
	m1.print();//直接进行打印
    return 0;
}

实现2:

//.h文件
//内联函数
inline void _print()
{
	cout << "内联函数" << endl;
}

//。cpp文件
int main()
{
    _print();
    return 0;
}

回答: 在C++中,内联函数inline)是一种特殊的函数,它的定义处增加了inline关键字。内联函数的作用是在函数调用时将函数的代码直接插入到调用处,而不是通过函数调用的方式执行。这样可以减少函数调用的开销,提高程序的执行效率。\[1\] 内联函数的定义方式与普通函数相似,但在函数定义处增加了inline关键字。例如,我们可以使用内联函数来实现交换两个数的值: ```cpp inline void swap(int *a, int *b){ int temp = *a; *a = *b; *b = temp; } ``` 在使用内联函数时,编译器会将函数的代码直接插入到函数调用处,而不是通过函数调用的方式执行。这样可以避免函数调用的开销,提高程序的执行效率。\[1\] 需要注意的是,内联函数适用于函数体较小且频繁调用的情况。对于函数体较大或者不频繁调用的函数,使用内联函数可能会导致代码膨胀,降低程序的执行效率。因此,需要根据实际情况来决定是否使用内联函数。\[3\] #### 引用[.reference_title] - *1* [【C++内联函数inline](https://blog.csdn.net/Jacky_Feng/article/details/120748428)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [[C++] 内联函数inline 以及 auto关键字 -- C++入门(4)](https://blog.csdn.net/qq_58325487/article/details/124735528)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值