zoukankan      html  css  js  c++  java
  • C++中函数调用操作符的重载

    1,本博文讲述函数对象问题;

     

    2,客户需求:

        1,编写一个函数:

           1,函数可以获得斐波那契数列每项的值;

           2,每调用一次返回一个值;

           3,函数可根据需要重复使用;

           4,代码示例:

    1 for(int i=0; i<10; i++)
    2 {
    3      cout << fib() << endl;
    4 }

          

    3,第一个解决方案编程实验:

        1,main.cpp 文件:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 int fib()
     7 {
     8     static int a0 = 0;  // 记录函数状态;
     9     static int a1 = 1;
    10     
    11     int ret = a1;
    12     
    13     a1 = a0 + a1;  // 更新 a1 的值;
    14     a0 = ret;  // a0 更新;
    15     
    16     return ret;
    17 }
    18 
    19 
    20 int main()
    21 {
    22     for(int i=0; i<5; i++)
    23     {
    24         cout << fib() << endl; //fib() 是带状态的函数,因为每次调用的结果是不同的,当输入的参数是一样的,返回结果必然是一样的函数叫做无状态函数;
    25     }
    26     
    27     cout << endl;
    28     
    29     for(int i=0; i<5; i++)
    30     {
    31         cout << fib() << endl;
    32     }
    33     
    34     return 0;
    35 }

     2,输出结果:

     1 1
     2 1
     3 2
     4 3
     5 5
     6 
     7 8
     8 13
     9 21
    10 34
    11 55

        3,带状态函数:每次调用的返回结果不同的函数,即相同的输入参数,不同的返回结果;

     4,两种方法实现带状态函数:

       1,是将函数内部要使用的变量用全局变量来代替,可以记录上一次函数调用的状态,但是代码中建议不要使用全局变量;

       2,是将函数内部要使用的变量用静态局部变量来代替;

     

    4,存在的问题:

        1,函数一旦开始调用就无法重来:

           1,静态局部变量处于函数内部,外界无法改变;

           2,函数为全局函数,是唯一的,无法多次独立使用;

           3,无法指定某个具体的数列项作为初始值;

        2,当用全局变量来使用时,可以达到目的,但是要在调用函数之前设置全局变量初始值,这样和用户的要求不符合;

          

    5,解决方案:

        1,函数对象:

           1,使用具体的类对象取代函数;

           2,该类的对象具备函数调用的行为;

               1,很了不起的行为;

           3,构造函数指定具体数列项的起始位置;

           4,多个对象相互独立的求解数据项;

          

    6,函数对象:

        1,函数调用操作符(()):

           1,只能通过类的成员函数重载;

           2,可以定义不同参数的多个重载函数;

           (3),C 和 C++ 中,函数调用操作符 “()” 其实是编译器内置的操作符,它的地位同 “[]” 一致,可以被重载,重载后一个类的对象可以当做 函数来使用;

          

    7,最终解决方案编程实验:

        1,main.cpp 文件:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Fib
     7 {
     8     int a0;
     9     int a1;
    10 public:
    11     Fib()
    12     {
    13         a0 = 0;
    14         a1 = 1;
    15     }
    16     
    17     /* 这个函数实现的非常经典 */
    18     Fib(int n)
    19     {
    20         a0 = 0;
    21         a1 = 1;
    22         
    23         for(int i=2; i<=n; i++)
    24         {
    25             int t = a1;
    26             
    27             a1 = a0 + a1;
    28             a0 = t;
    29         }
    30     }
    31     
    32     int operator () ()  // 重载函数调用操作符 (),这样类的对象就可以当做函数来调用;
    33     {
    34         int ret = a1;
    35     
    36         a1 = a0 + a1;
    37         a0 = ret;
    38         
    39         return ret;
    40     }
    41 };
    42 
    43 int main()
    44 {
    45     Fib fib;
    46     
    47     for(int i=0; i<10; i++)
    48     {
    49         cout << fib() << endl;  // fib 不是函数名,而是对象名,这里将对象当做函数调用;
    50     }
    51     
    52     cout << endl;
    53     
    54     for(int i=0; i<5; i++)
    55     {
    56         cout << fib() << endl;
    57     }
    58     
    59     cout << endl;
    60     
    61     Fib fib2(10);  // 第二个对象和第一个独立,也就可以从头开始了;
    62     
    63     for(int i=0; i<5; i++)
    64     {
    65         cout << fib2() << endl;
    66     }
    67     
    68     return 0;
    69 }

     2,输出结果:

     1 1
     2 1
     3 2
     4 3
     5 5
     6 
     7 8
     8 13
     9 21
    10 34
    11 55
    12 
    13 5
    14 8
    15 13
    16 21
    17 34

        3,提供函数对象,通过私有成员变量来记录函数调用状态,意味着绕开了局部     变量和全局变量这样的限制;

        4,带状态函数实现方法:

           1,用全局变量实现函数内部的使用变量;

           2,静态局部变量;

           3,函数对象中的成员变量;

     

    8,小结:

        1,函数调用操作符(())是可重载的;

        2,函数调用操作符只能通过类的成员函数重载;

           1,和 “=” 相同;

        3,函数调用操作符可以定义不同参数的多个重载函数;

        4,函数对象用于在工程中取代函数指针;

           1,实际的 C++ 工程项目中,我们要尽量少的使用原生的指针;

           2,字符串可以使用字符串类而不用字符数组,数组可以使用数组对象,函数指针可以用函数对象,这些对象都是用于在工程中取代指针;

  • 相关阅读:
    【转】JSch
    【转】JSch
    【转】class卸载、热替换和Tomcat的热部署的分析
    关于Tomcat自动加载更新class的小技巧
    MySQL中order by中关于NULL值的排序问题
    MySQL触发器使用详解
    QuartZ Cron表达式
    JDBC的URL设置allowMultiQueries的原因
    CRT:C运行库简介
    IntelliJ IDEA安装AngularJS插件
  • 原文地址:https://www.cnblogs.com/dishengAndziyu/p/10913302.html
Copyright © 2011-2022 走看看