C++11中内联函数(inline)用法实例

 更新时间:2022年10月31日 15:59:13   作者:BUG_C++  
内联函数本质还是一个函数,但在声明的时候,函数体要和声明结合在一起,否则编译器将它作为普通函数来对待,下面这篇文章主要给大家介绍了关于C++11中内联函数(inline)的相关资料,需要的朋友可以参考下

inline 是什么?

inline是C++ 11引入的关键字,在函数声明or定义时,返回类型前加上关键字inline,即可以把函数指定为内联函数。

引入inline的目的是什么?

目的是解决一些频繁调用的函数大量消耗栈空间(栈内存)的问题。另一方面用于替换C语言的宏(相比较宏是无法在进行类型检查)

内联函数的特点

  • 内联函数的函数内容本质上是写在调用内联函数的地方;
  • 内联函数本质上没有入栈出栈的开销;
  • 和宏定义相比,内联函数更加安全,编译器会根据函数的要求进行严格的类型和作用域检查,保证调用无误;
  • 内联函数一般上不包含循环、递归、switch或较长的代码 等复杂操作;
  • 类声明中定义的函数,除虚函数外的其他函数都会自动隐式地当成内联函数;

内联函数的写法

这里的一个关键点,inline必须与函数定义放在一起才能使函数成为内联函数,仅将inline放在函数声明前面不起任何作用。

inline是一种“用于实现”的关键字,不是一种“用于声明”的关键字。

//在头文件中可以进行显示声明

//方式1 加 inline(建议使用)
inline int TestFunc(int a, int b);

//方式2 原始常见声明方式
int TestFunc(int a, int b);

//在源文件中定义
//正确
inline int TestFunc(int a, int b){
    //do something
    return 0;
}
//错误
int TestFunc(int a, int b){
    //do something
    return 0;
}

隐式内联和显式内联

隐式内联的写法

class CppObj {
    int TestFuncA() { return 0; }       //隐式内联
    vitrual int TestFuncB() { return 0; }    //虚函数不会进行隐式内联   
}

显式内联的写法

class CppObj {
    int TestFuncA();
    inline int TestFuncB();
    vitrual int TestFuncC();
}
inline int CppObj::TestFuncA() {   //显式内联
    return 0; 
} 

inline int CppObj::TestFuncB() {   //显式内联
    return 0; 
} 

inline 函数的编译器处理

inline函数仅仅是一个开发者对编译器的建议,至于最后能否真正内联,需要看编译器的意思。如果编译器判定函数不复杂,能在调用点展开,就会真正内联。

内联函数优缺点

  • 优点
    • 内联函数相比宏函数来说,在代码调用时会做安全检查和类型转换(同普通函数),而宏定义则不会;
    • 宏定义不可以在运行时可调试,但内联函数可以;
    • 内联函数同宏函数一样会在被调用处进行展开,无需参数压栈、栈帧开辟与回收,结果返回等,从而能提高代码的运行速度。
  • 缺点
    • 代码膨胀。内联是以代码膨胀(复制)为代价,是典型的以空间换时间的做法。
    • 内联函数不可控。内联函数只是编码者对编译器的建议,是否对函数内联,最终决定权在于编译器。
    • inline 函数无法随着函数库升级而升级。inline函数的改变需要重新编译,不像 non-inline 可以直接链接。

虚函数可以是内联函数吗?

  • 虚函数可以是内联函数;
  • inline是可以修饰虚函数;

虚函数内联条件?

可以内联的条件,编译器具有实际对象而不是对象的指针或引用时才会,所以当虚函数表现多态性的时候不能内联。

虚函数表现多态性的时候不能内联

内联是在编译期进行的,但虚函数的多态性在运行期,所以编译器无法知晓运行期具体调用哪个代码

代码释义

#include <iostream>
using namespace std;
class Base {
public:
	virtual ~Base() {}
	inline virtual void FuncName() { cout << "this is Base " << endl; }
};

class Derived : public Base {
public:
	inline virtual void FuncName() { cout << "this is Derived" << endl; }
};

int main()
{
	// 编译器具有实际对象,所以它可以是内联的.
	Base b;
	b.FuncName();

	// 编译器具有对象的指针,呈现多态性,运行时期才能确定,所以不能内联。
	Base* p = new Derived();
	p->FuncName();

	delete p;
	p = nullptr;

	system("pause");
	return 0;
}

参考连接:

Are “inline virtual” member functions ever actually “inlined”?

总结 

到此这篇关于C++11中内联函数(inline)用法的文章就介绍到这了,更多相关C++11内联函数inline内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++学习笔记之pimpl用法详解

    C++学习笔记之pimpl用法详解

    在编写稳定代码是,管理好代码间的依赖性是不可缺少的一个环节。特别是库文件的编写中,减少代码间的依赖性可以提供一个“干净”的接口。下面这篇文章主要给大家介绍了关于C++中pimpl用法的相关资料,需要的朋友可以参考下。
    2017-08-08
  • C语言中0、‘\0‘、‘0‘、NULL以及类型转化

    C语言中0、‘\0‘、‘0‘、NULL以及类型转化

    在C语言中, NULL和0的值都是一样的,但是为了目的和用途及容易识别的原因,下面这篇文章主要给大家介绍了关于C语言中0、‘\0‘、‘0‘、NULL以及类型转化的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-08-08
  • C/C++中智能指针的用法详解

    C/C++中智能指针的用法详解

    C/C++中,指针是一个非常重要的概念,其强大但也麻烦,麻烦之处就在于一旦你申请了内存,那就必须要手动去释放内容,否则就会造成内存泄漏。所以智能指针的作用就是防止我们麻痹大意忘记释放内存,帮助我们管理内存的,本文就来聊聊智能指针的用法
    2023-01-01
  • 超详细解析C++实现归并排序算法

    超详细解析C++实现归并排序算法

    归并排序是比较稳定的排序方法。它的基本思想是把待排序的元素分解成两个规模大致相等的子序列。本文将用C++实现这一排序算法,需要的可以参考一下
    2022-09-09
  • C++ opencv图像处理实现图片边缘检测示例

    C++ opencv图像处理实现图片边缘检测示例

    这篇文章主要为大家介绍了C++ opencv实现图片边缘检测示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • C语言的常量,字符串,转义字符,注释你都了解吗

    C语言的常量,字符串,转义字符,注释你都了解吗

    这篇文章主要为大家详细介绍了C语言的常量,字符串,转义字符,注释,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C语言之详解静态变量static

    C语言之详解静态变量static

    在C语言中static是用来修饰变量和函数的,这篇文章详细介绍了static主要作用,文章中有详细的代码实例,需要的朋友可以参考阅读
    2023-04-04
  • C语言中联合体与共用体和枚举使用语法示例

    C语言中联合体与共用体和枚举使用语法示例

    这篇文章主要介绍了C语言中联合体与共用体和枚举使用语法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • C++中std::string::npos的用法

    C++中std::string::npos的用法

    这篇文章主要介绍了C++中std::string::npos的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C语言实现简单版三子棋

    C语言实现简单版三子棋

    这篇文章主要为大家详细介绍了C语言实现简单版三子棋,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10

最新评论