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++内联函数的主要内容,如果未能解决你的问题,请参考以下文章