TA的每日心情 | 开心 2021-12-13 21:45 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
|
在上章17.C++-string字符串类(详解)学习了string类,发现可以通过[ ]重载操作符来访问每个字符。
比如:
- string s="SAD";
- for(int i=0,i< s.length();i++)
- cout<<s[i]<<endl;
复制代码
接下来,我们来自己写个[ ]重载操作符,来模拟string类
- #include <iostream>
- #include "string.h"
- class string
- {
- private:
- char *str;
- int len;
- public:
- string(const char *p=0)
- {
- if(p!=NULL)
- {
- len=strlen(p);
- str = new char[len];
- strcpy(str,p);
- }
- else
- {
- len=0;
- str = new char[1];
- str[0]="\0";
- }
- }
- char& operator [](int i)
- {
- return str[i];
- }
- int length()
- {
- return len;
- }
- };
- int main()
- {
- string s="SAD";
- for(int i=0;i< s.length();i++)
- std::cout << s[i] << std::endl;
- return 0;
- }
复制代码
运行打印:
函数对象
函数对象是指该对象具备函数的行为
函数对象,是通过()调用操作符声明得到的,然后便能通过函数方式来调用该对象了.
()调用操作符可以定义不同参数的多个重载函数
()调用操作符只能通过类的成员函数重载(不能通过全局函数)
函数对象用于在工程中取代函数指针
比如,定义一个函数对象t:
- class Test{
- public:
- void operator () (void) //通过()重载操作符,来使对象具备函数的行为
- {
- cout<<"hello"<<endl;
- }
- };
- int main()
- {
- Test t;
- t(); //打印"hello"
- }
复制代码
函数对象与普通函数区别
函数对象
可以封装自己的成员以及其它函数,所以能够更好的面向对象.
普通函数
往往只具备逻辑关系,并且没有固定的成员,因为普通函数一被调用完后,里面的内容便被摧毁了,除非使用全局变量,但是全局变量又不具备封装性.
接下来,我们来个普通函数和函数对象的示例,便知道两者的区别了.
需求如下:
通过一个函数,来获取斐波那契数列每项的值
每调用一次函数,便返回一个值
可以重复使用
普通函数实例:
- #include <iostream>
- using namespace std;
- int cnt0=0;
- int cnt1=1;
- void fib_set(int n) //设置斐波那契数列为哪一项,使fib()能重复使用
- {
- cnt0=0;
- cnt1=1;
- for(int i=0;i<n;i++)
- {
- int tmp=cnt1;
- cnt1=cnt0+cnt1;
- cnt0=tmp;
- }
- }
- int fib() //计算出一项值
- {
- int tmp=cnt1;
- cnt1=cnt0+cnt1;
- cnt0=tmp;
- return tmp;
- }
- int main()
- {
- for(int i=0;i<5;i++)
- cout<<fib()<<endl; //打印1~5项值
- fib_set(0); //从新设置项数位0
- for(int i=0;i<5;i++)
- cout<<fib()<<endl; //再次打印1~5项值,使它能重复使用
- return 0;
- }
复制代码
运行打印:
从上面代码可以看到,通过普通函数实现的需求,还需要两个全局变量才行,这在大项目里,完全不可取的,若项目里,像这样的模块多的话,那得有多少个全局变量啊?并且这些全局变量能够随意被破坏,没有一点封装性.
接下来,通过函数对象来完成这个需求:
- #include <iostream>
- using namespace std;
- class Fib{
- private:
- int cnt0;
- int cnt1;
- public:
- Fib(int n=0)
- {
- cnt0=0;
- cnt1=1;
- }
- void operator =(int n)
- {
- cnt0=0;
- cnt1=1;
- for(int i=0;i<n;i++)
- {
- int tmp=cnt1;
- cnt1+=cnt0;
- cnt0=tmp;
- }
- }
- int operator () ()
- {
- int tmp=cnt1;
- cnt1+=cnt0;
- cnt0=tmp;
- return cnt0;
- }
- };
- int main()
- {
- Fib fib;
- for(int i=0;i<5;i++)
- cout<<fib()<<endl; //打印1~5项值
- fib=0; //从新设置项数为0
- for(int i=0;i<5;i++)
- cout<<fib()<<endl; //打印1~5项值
- return 0;
- }
复制代码
运行打印:
从上面代码看到,使用函数对象后,便不需要使用全局变量了. |
|