c++内联函数

Posted 只会C的码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++内联函数相关的知识,希望对你有一定的参考价值。

之前面试正好被问到这个问题,知识盲区呀,特意去查了一下,整理了相关内容,记录在这里,以后再也不怕面试官问了,哈哈哈。

1、内联函数

在高级程序语言编程中,我们经常使用函数,使用函数的好处就是修改方便,便于我们代码的设计,但是函数存在的缺点就是:

调用函数速度很慢:调用前要先保存到寄存器,并在返回时恢复,复制实参,程序还必须转向一个新的位置执行

#include<iostream>
using namespace std;

int func(int a,int b)
{
   return a + b;
}

int main()
{
   int x = 10;
   int y =20;
   int c = func(x,y);  //这里调用函数,需要进行实参的复制,还有程序会跑到上面函数的位置进行计算,计算完的返回值,又要返回到这里,速度会很慢
   cout <<"c=" << c << endl;  //30
   system("pause");

   return 0;
}

c++中提出使用内联函数来提高函数执行的效率,用关键字inline放在函数定义之前(注意是定义之前,不是声明)

采用内联函数速度变快了(604和647对比)

定义在类内部的成员函数将自动地成为内联函数

class A
{
   public:
   void Foo(int x,int y){};  //成员函数,自动地成为内联函数
}

内联函数应该在头文件中定义,这一点不同于其他函数,编译器在调用点内联地展开,必须能够找到inline函数的定义菜鸟呢个将调用函数替换为函数代码,而对于在头文件中仅有声明是不够的。当然,也可以放在源文件中,但此时只有定义那个源文件可以使用它,而且必须为每一份源文件拷贝一份定义,头文件也需要拷贝,只是编译器代替你完成,所以最好放在头文件中比较方便。

谨慎使用内联函数

内联函数

#include <iostream>
#include "inline.h"

using namespace std;

/**
* @brief inline要起作用,inline要与函数定义放在一起,inline是一种“用于实现的关键字,而不是用于声明的关键字”
*
* @param x
* @param y
*
* @return
*/
int Foo(int x,int y);  // 函数声明
inline int Foo(int x,int y) // 函数定义
{
   return x+y;
}

// 定义处加inline关键字,推荐这种写法!
inline void A::f1(int x){

}

int main()
{


   cout<<Foo(1,2)<<endl;

}
/**
* 编译器对 inline 函数的处理步骤
* 将 inline 函数体复制到 inline 函数调用点处;
* 为所用 inline 函数中的局部变量分配内存空间;
* 将 inline 函数的的输入参数和返回值映射到调用方法的局部变量空间中;
* 如果 inline 函数有多个返回点,将其转变为 inline 函数代码块末尾的分支(使用 GOTO)。
*/

以下情况不宜用内联:

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

(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。

(3)、递归尽量不要使用内联,递归因为效率本来就低,使用内联函数也不会有多快。

虚函数(virtual)可以是内联函数(inline)吗?

  • 虚函数可以是内联函数,内联是可以修饰虚函数的,但是当虚函数表现多态性的时候不能内联。

  • 内联是在编译器进行编译期内联,而虚函数的多态性在运行期,编译器无法知道运行期调用哪个代码,因此虚函数表现为多态性时(运行期)不可以内联。

  • inline virtual 唯一可以内联的时候是:编译器知道所调用的对象是哪个类(如 Base::who()),这只有在编译器具有实际对象而不是对象的指针或引用时才会发生。

    /*
    内联函数
    */
    #include<iostream>
    using namespace std;
    #include<time.h>

    class Base
    {
       public:
       inline virtual void who()
      {
           cout << "i am Base" << endl;
      }

       virtual ~Base(){};  //虚析构函数
    };

    class Derived:public Base
    {
       public:
       inline void who()
      {
           cout << " i am Derived" << endl;
      }
    };

    int main()
    {
       //此处虚函数who()是通过Base的具体对象b来调用的,所以确定了编译时间,所以可以使内联的,但是最终内联还是要取决于编译器
       Base b;
       b.who();  //这里调用是内联的

       Base *ptr = new Derived();  //这里涉及到向上转型,虽然是子类new了对象,但是传递给左边的父类,是多态调用,需要在运行期间才能确定具体的对象调用,所以不能为内联
       ptr->who();

       delete ptr;  //程序员自己申请的内存需要自己释放
       ptr=nullptr;  //避免出现野指针,将指针置空

       return 0;
    }

内联函数的基本知识就是这些,你get到了吗?

下面给大家看看计算机现在有多卷,小学生都人工智能了,着实吓我一跳,还yolo5模型,赶紧加把劲学习,缩小差距。



以上是关于c++内联函数的主要内容,如果未能解决你的问题,请参考以下文章

关于C++内联函数

C++ 为啥要引入内联函数、、

C++基础--inline

C++内联函数

C++内联函数

C++内联函数