zoukankan      html  css  js  c++  java
  • 第35课 函数对象分析(函数操作符()重载)

    1. 为什么需要函数对象

    (1)案例

      ①编写一个函数,使函数可以获得斐波那契数列每项的值

      ②每调用一次返回一个值

      ③函数可根据需要重复使用

          

    【编程实验】第一个解决方案 

     1 /*斐波那契数列:0、1、1、2、3、5、8、13、21、
     2 递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)*/
     3 
     4 #include<iostream>
     5 #include<string>
     6 
     7 using namespace std;
     8 
     9 int fib()
    10 {
    11     static int a0 = 0;   // 静态局部变量---记录函数状态
    12     static int a1 = 1;   //静态局部变量
    13 
    14     int ret = a1;        //第一次调用返回1,用a1初始化
    15 
    16     a1 = a0 + a1;        //a1更新下一次的值
    17     a0 = ret;
    18 
    19     return ret;          //a0是上一次a1的值
    20 }
    21 
    22 int main()
    23 {
    24     //注意每次调用fib(),形式完全相同,但函数返回的结果不同!
    25 
    26     //这叫有状态函数,因为函数内部会通过static变量
    27 
    28     //记录上次的状态
    29 
    30     for (int i = 0; i < 10; i++)
    31     {
    32         cout << fib() << endl;   //1,1,2,3,5,8,13,21,34,55
    33     }                            
    34 
    35     cout << endl;
    36 
    37 
    38     //函数不能回到初始状态,会从新的状态开始,继续计算。----   //无法从第一项重新开始
    39     for (int i = 0; i < 5; i++)
    40     {
    41         cout << fib() << endl;  //89,144,233,377,610,从上次结果开始
    42     }
    43 
    44     //fib()带状态函数:输入参数一样,但是每次返回值不同,要求函数返回的时候不会摧毁---静态局部变量实现
    45     //局部变量在函数返回的时候不会被摧毁  但是c++ 避免使用局部变量   所以要使用类的静态局部变量
    46 
    47 
    48     return 0;
    49 }

    (2)存在的问题

      ①函数一旦开始调用无法重来(因为这种函数是有状态的函数

      ②静态局部变量处理函数内部外界无法改变

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

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

    (3)解决方案:函数对象

      ①使用具体的类对象取代函数

      ②该类的对象具备函数调用的行为

      ③构造函数指定具体的数列项的起始位置

      ④多个对象相互独求解数列项

    2. 函数对象

    (1)函数调用操作符()----编译器内置的操作符,与数组访问操作符一致,重载以后一个类对象可以当作函数使用

      ①只能通过类的成员函数重载

      ②可以定义不同参数多个重载函数

     1 #include<iostream>
     2 #include<string>
     3 
     4 //函数对象取代函数,该类的对象具备函数调用的行为   构造函数支持指定具体数列项的起始位置
     5 //函数调用操作符() 只能通过类的成员函数重载,一个类的对象可以当做函数来使用
     6 
     7 using namespace std;
     8 
     9 class Fib
    10 {
    11     int a0;        //构造函数进行初始化
    12     int a1;
    13 
    14 public:
    15 
    16 //  Fib() :a0(0), a1(1) {}
    17 
    18     Fib()
    19     {
    20         a0 = 0;
    21         a1 = 1;
    22     }
    23 
    24     Fib(int n)   //指定某个项作为初始值
    25     {
    26         a0 = 0;
    27         a1 = 1;
    28 
    29         for (int i = 2; i < n; i++)
    30         {
    31             int t = a1;
    32 
    33             a1 = a0 + a1;  //推算从n项开始,a0 a1的值
    34             a0 = t;
    35         }
    36     }
    37 
    38     int  operator() ()     //操作符重载----(重载操作符本质上是个函数),这种方式就像函数名调用函数一样直观!
    39     {
    40         int ret = a1;
    41         a1 = a0 + a1;
    42         a0 = ret;
    43         return ret;
    44     }
    45 };
    46 
    47 
    48 int main()
    49 {
    50     Fib fib;   //定义对象------取代函数
    51 
    52     for (int i = 0; i < 10; i++)
    53     {
    54         cout << fib() << endl;      //操作符重载----类的对象当作函数使用
    55     }
    56 
    57     cout << endl;
    58 
    59     for (int i = 0; i <5; i++)
    60     {
    61         cout << fib() << endl;  //1,1,2,3,5,8,13,21,34,55
    62     }
    63 
    64     Fib fib1;   
    65 
    66     for (int i = 0; i < 10; i++)
    67     {
    68         cout << fib1() << endl;  //89,144,233,377,610,从上次结果开始
    69     }
    70 
    71     cout << endl;
    72 
    73     Fib fib1(10);
    74 
    75     for (int i = 0; i < 5; i++)
    76     {
    77         cout << fib1() << endl; //55,89,144,233,377
    78     }
    79 
    80     cout << endl;
    81 
    82     return 0;
    83 }

    3. 小结

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

    (2)函数调用操作符()只能通过成员函数重载

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

    (4)函数对象用于在工程中取代函数指针---------避免使用原生指针

  • 相关阅读:
    Linux下Utuntu使用
    模拟退火算法
    五大常用算法:分治、动态规划、贪心、回溯和分支界定
    图像处理与机器视觉行业分析
    数字图像处理知识结构整理
    算法之美--读书笔记
    台湾大学林轩田和李宏毅机器学习课程
    下载SCI论文
    OpenCV机器学习库函数--SVM
    fmri的图像数据在matlab中显示,利用imagesc工具进行显示,自带数据集-by 西南大学xulei教授
  • 原文地址:https://www.cnblogs.com/liuyueyue/p/13379345.html
Copyright © 2011-2022 走看看