c++内联函数

内联函数定义

    内联函数使用inline关键字定义, 并且函数体和申明必须结合在一起, 否则编译器将他作为普通函数对待。

 inline void function(int x); //仅仅是申明函数,没有任何效果
inline void function(int x) //正确
{
    return ++x;
}
在类内部定义的函数自动的为内联函数不需要加关键字inline。
class point
{
  int i;
public:
  void SetValue(int x) //内联函数
  {
    i = x;
  }
}

 
总结:在类定义中定义的成员函数,或者函数定义前有inline关键字(不一定是类的成员函数),称为内联函数
 
为什么需要内联函数?
 
     解决多次函数调用的效率问题
 
内联函数的原理
 
普通函数:在运行时程序从主调函数的调用点转去执行被调用函数,待被调用函数执行完毕后,再返回到主调函数的调用点的下一语句继续执行。
 
内联函数:编译程序将该函数的代码直接复制到调用点,在运行时不存在函数调用的过程,也就没有程序流程的跳转和返回开销
 
内联函数可加快程序代码的执行速度,但这是以增加可执行程序的大小为代价的。
 
源程序中调用内联函数与调用普通函数的方法相同。
 
内联函数 vs. 宏定义
 
从运行效率来看,内联函数与宏定义类似,然而内联函数可以被编译程序所识别,而宏则是通过简单的文本替换来实现的。
编译程序可对内联函数的参数作类型检查,没有宏定义带来的副作用。
 
譬如,宏替换可完成简单的函数功能
#define abs(v) (v < 0 ? –v : v)
abs(a+b) 不能得到期望的结果
#define abs(v) ((v)<0?-(v):(v))
abs(++a) 不能得到期望的结果
 
内联函数的限制
 
注意:不是任何一个函数都可定义成内联函数。
 1 内联函数的函数体内不能含有复杂的结构控制语句,如:switch和while,否则编译器将不管此函数是否声明为内联函数,一律将该函数视为普通函数,产生函数调用代码。
 
 2递归函数不能被用来作为内联函数。
 
3内联函数一般适合于只有1~5行语句的小函数,对一个含有很多语句的大函数,没有必要使用内联函数来实现。
 

函数声明或定义中函数返回类型前加上关键字inline(只要一种即可)即把min()指定为内联。

inline int min(int first, int secend) {/****/};

inline 函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数。与非inline函数不同的是,inline函数必须在调用该函数的每个文本文件中定义。当然,对于同一程序的不同文件,如果C++ inline函数出现的话,其定义必须相同。对于由两个文件compute.C和draw.C构成的程序来说,程序员不能定义这样的min()函数,它在compute.C中指一件事情,而在draw.C中指另外一件事情。如果两个定义不相同,程序将会有未定义的行为:

为保证不会发生这样的事情,建议把inline函数的定义放到头文件中。在每个调用该inline函数的文件中包含该头文件。这种方法保证对每个inline函数只有一个定义,且程序员无需复制代码,并且不可能在程序的生命期中引起无意的不匹配的事情。

内联函数的编程风格

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

如下风格的函数Foo 不能成为内联函数:

  1. inline void Foo(int x, int y);   
  2. // inline 仅与函数声明放在一起   
  3. void Foo(int x, int y){}  

而如下风格的函数Foo 则成为内联函数:

  1. void Foo(int x, int y);   
  2. inline void Foo(int x, int y)   
  3. // inline 与函数定义体放在一起{} 

所以说,C++ inline函数是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。一般地,用户可以阅读函数的声明,但是看不到函数的定义。尽管在大多数教科书中内联函数的声明、定义体前面都加了inline 关键字,但我认为inline 不应该出现在函数的声明中。这个细节虽然不会影响函数的功能,但是体现了高质量C++/C 程序设计风格的一个基本原则:声明与定义不可混为一谈,用户没有必要、也不应该知道函数是否需要内联。

定义在类声明之中的成员函数将自动地成为内联函数。

将成员函数的定义体放在类声明之中虽然能带来书写上的方便,但不是一种良好的编程风格,上例应该改成

// 头文件  
class A  
{  
public:  
void Foo(int x, int y);  //void 之前可以加inline,加不加都可以
}  
// 定义文件  
inline void A::Foo(int x, int y){}  

 另一篇文章:

 内联函数必须是和函数体在一起,才有效。像这样的申明Inline Tablefunction(int I)是没有效果的,编译器只是把函数作为普通的函数申明,我们必须定义函数体。

Inline tablefunction(int I) {return I*I};

这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调用。但是执行速度确比一般函数的执行速度要快。


我们也可以将定义在类的外部的函数定义为内联函数,比如:

Class TableClass{
 Private:
  Int I,j;
 Public: 
  Int add() { return I+j;};
  Inline int dec() { return I-j;}
  Int GetNum();
}
inline int tableclass::GetNum(){
return I;
}

 上面申明的三个函数都是内联函数。在C++中,在类的内部定义了函数体的函数,被默认为是内联函数。而不管你是否有inline关键字。

  内联函数在C++类中,应用最广的,应该是用来定义存取函数。我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们类成员的数据了。对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把这些读写成员函数定义成内联函数的话,将会获得比较好的效率。

Class sample{
 Private:
  Int nTest;
 Public:
  Int readtest(){ return nTest;}
 Void settest(int I) {nTest=I;}
}

  当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样了

 
原文地址:https://www.cnblogs.com/youxin/p/2542229.html