内联函数(inline function)

一. 为什么要有内联函数

 第一个在c中也会出现,宏看起来像一个函数调用,但是会有隐藏一些难以发现的错误。

 第二个问题是c++特有的,预处理器不允许访问类的成员,也就是说预处理器宏不能用作

类类的成员函数。

二. 宏函数和内联函数的区别 

       宏函数的替换是发生在预处理阶段,内联函数的替换是发生在编译阶段;宏函数容易出错,内联函数不会;内联函数和宏函数一样,都省去了调用函数的开销 。

代码实现 

#include <iostream>

#define MYADD(a, b)  (a+b)
#define MYCOMPARE(a, b) (a)<(b)?(a):(b)
using namespace std;

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

void test01()
{
    int a = 10;
    int b = 20;
    //int c = MYADD(a, b)*5;// a+b*5 替换发生在预处理阶段
    int c = MyAdd(a, b) * 5;// (a + b)*5 替换发生在编译阶段 也和宏函数一样不会有函数调用的开销
    cout << c << endl;
}

inline int mycpmpare(int a, int b)
{
    return a < b ? a : b;
}

void test02()
{
    int a = 1;
    int b = 5;
    //int c = MYCOMPARE(++a, b);// ++a<b?++a:b
    int c = mycpmpare(++a, b);
    cout << c << endl;
}

int main()
{
    test01();
    test02();
    return 0;
}

三. 内联函数的基本概念

       预定义宏的概念是用内联函数来实现的,而内联函数本身也是一个真正的函数。内联函数具有普通函数的所有行为。唯一不同之处在于内联函数会在适当的地方像预定义宏一样展开,所以不需要函数调用的开销。因此应该不使用宏,使用内联函数。在普通函数(非成员函数)前面加上inline关键字使之成为内联函数。

但是必须注意:函数体和声明结合在一起,否则编译器将它作为普通函数来对待。

 四. 类的成员函数默认编译器会将它做成内联函数

     任何在类内部定义的函数自动成为内联函数

 class Person
{ 
 public:
	Person()
    { 
       cout << "构造函数!" << endl; 
    }
	void PrintPerson()
    { 
       cout << "输出Person!" << endl; 
    }	
}

五. 内联函数和编译器

内联函数并不是何时何地都有效,为了理解内联函数何时有效,应该要知道编译器碰到内联函数会怎么处理?

        对于任何类型的函数,编译器会将函数类型(包括函数名字,参数类型,返回值类型)放入到符号表中。同样,当编译器看到内联函数,并且对内联函数体进行分析没有发现错误时,也会将内联函数放入符号表。

当调用一个内联函数的时候,编译器首先确保传入参数类型是正确匹配的,或者如果类型不正完全匹配,但是可以将其转换为正确类型,并且返回值在目标表达式里匹配正确类型,或者可以转换为目标类型,内联函数就会直接替换函数调用,这就消除了函数调用的开销。假如内联函数是成员函数,对象this指针也会被放入合适位置。

类型检查和类型转换、包括在合适位置放入对象this指针这些都是预处理器不能完成的。

但是c++内联编译会有一些限制,以下情况编译器可能考虑不会将函数进行内联编译:

 不能存在任何形式的循环语句

 不能存在过多的条件判断语句

 函数体不能过于庞大

 不能对函数进行取址操作内联仅仅只是给编译器一个建议,编译器不一定会接受这种建议

如果你没有将函数声明为内联函数,那么编译器也可能将此函数做内联编译。一个好的编译器将会内联小的、简单的函数。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值