zoukankan      html  css  js  c++  java
  • 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;}
    }

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

     
  • 相关阅读:
    上涨、下跌、震荡,我只做下跌 (有钱人赚钱太有心机!
    股票操作指南
    股票要素与心理学研究
    时序图组成
    软件描述的静态与动态
    用dedecms做网站时,空间服务器选择IIS还是apache???
    dedecms 图集标签{dede:productimagelist} {dede:field name='imgurls'}&nbs
    dede内容页调用图片集下所有图片方法!
    dede文章插入分页符不起作用,编辑器中出现分页符,导致文章显示不全
    dede织梦怎么修改description的字数
  • 原文地址:https://www.cnblogs.com/youxin/p/2542229.html
Copyright © 2011-2022 走看看