C++内联函数

内联函数的定义:以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,如果没有压栈的开销,内联函数提升程序运行的效率。

为什么使用内联函数:

1.内联函数最初的目的是代替部分#define宏定义

原因:a.宏是预处理指令,在预处理的时候把所有的宏名用宏体来替换;内联函数是函数,在编译阶段把所有调用内联函数的地方把内联函数插入

        b.宏没有类型检查,无论对还是错都是直接替换;而内联函数在编译时进行安全检查

        c.宏的编写有很多限制,例如只能写一行,不能使用return控制流程等

        d.对C++而言,使用宏代码还有另一种缺点:无法操作类的私有数据成员(因为宏是在编译之前处理的,它不知道类的访问权限设置)

2.使用内联函数代替普通函数的目的是:提高程序的运行效率

原因:普通函数频繁调用的过程消耗栈空间,函数调用时要花费开辟栈区的时间和返回主函数寻址的时间;内联函数节省了开辟函数栈和寻址的时间。

如果是一个几十行的函数,函数本身执行就很耗时,那调用函数、创建栈帧(每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量,其实就是函数运行时开辟的函数栈)的一两行可以忽略不计;但是如果一个函数本身就一两行,因为调用函数本身而产生的那一部分消耗就格外突出,而宏或者内联的提前置换就显得格外优秀,提高了效率。

注意: 1.函数前面加上inline不一定会有效果,使用inline关键字修饰函数只是一种提示,编译器不一定认

         2.如果不加inline不一定不是内联函数,存在隐式内联,不用inline关键字,C++中在类内定义的所有函数都自动称为内联函数

         3.内联函数不应定会展开,要看编译器认不认

         4.首先需要满足有inline修饰或者是类中定义的函数,然后再由编译器决定的情况下内联函数会展开

内联函数的特点:

1.inline是一种以空间换时间的做法,省去调用函数,建立栈帧得额外开销,但是如果代码很长(一般是10行左右,具体取决于编译器),或者有递归函数,即使函数前面声明了inline,那么编译器也不会让该函数成为内联函数。

2.inline对于编译器而言只是一个建议,编译器会自动优化,如果定义的函数很长或者递归函数等等,编译优化时会忽略掉内联;而类的构造函数,析构函数和虚函数往往不是内联函数的最佳选择。

3.inline不可以声明和定义分离,.h文件中使用inline声明内联函数(内联展开是在编译时进行的,只有链接的时候源文件之间才有关系),.cpp文件中如果不使用inline定义函数,会报错链接错误。

内联函数与普通函数的区别:

1.内联函数在编译时展开,没有函数调用的开销,但可能会增加代码体积

2.普通函数在运行时进行调用,有一定的调用开销,但代码更紧凑

3.内联函数的定义通常放在头文件中,而普通函数定义放在源文件中,头文件只包含函数声明

定义:

在函数声明前加上"inline"关键字来定义内联函数

inline nint add(int a,int b)
{
    return a+b;
}

使用:使用时和普通函数一样调用即可

内联分为显式内联和隐式内联

显式内联:需要使用inline关键字,是在建议编译器将该函数作为内联函数处理。

// 显式内联函数定义
inline int add(int a, int b) {
    return a + b;
}
int main() {
    int result = add(3, 5);
    // 在这里,编译器可能会将add函数的代码直接插入到调用点
    return 0;
}

隐式内联:类内的成员函数的定义直接写在类的声明中时,不需要inline关键字,编译器会隐式地将其视为内联函数候选。

class Work {
public:
    // 隐式内联成员函数
    int multiply(int a, int b) {
        return a * b;
    }
};
int main() {
    Work w;
    int result = w.multiply(4, 6);
    // 这里编译器可能会将multiply函数的代码直接插入到调用点
    return 0;
}

内联函数的使用场景

1.当对程序执行性能有要求时,那么就适当使用内联函数

2.当想宏定义一个函数时,使用内联函数

3.写一些功能专一且性能关键的函数,这些函数的函数体不大,包含了很少的执行语句。通过inline声明,编译器不需要跳转到内存其他地址去执行函数调用,也不需要保留函数调用时的现场数据。

4.在类内部定义的函数会默认声明为inline函数,这有利于类实现细节的隐藏。(大部分是不推荐默认inline的)

不建议使用:

1.如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。

2.如果函数体内出现循环或者开关语句还有递归;那么执行函数体内代码的时间要比函数调用的开销大,还有可能造成栈空间枯竭。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值