第35课 函数对象分析(函数操作符()重载)
Posted liuyueyue
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第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)函数对象用于在工程中取代函数指针---------避免使用原生指针
以上是关于第35课 函数对象分析(函数操作符()重载)的主要内容,如果未能解决你的问题,请参考以下文章