Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 327|回复: 0

[默认分类] 18.C++-[ ]操作符使用 、函数对象与普通函数区别(详解)

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-3-27 09:22:12 | 显示全部楼层 |阅读模式
    在上章17.C++-string字符串类(详解)学习了string类,发现可以通过[ ]重载操作符来访问每个字符。
    比如:

    1. string s="SAD";
    2. for(int i=0,i< s.length();i++)
    3. cout<<s[i]<<endl;
    复制代码


    &nbsp;
    接下来,我们来自己写个[ ]重载操作符,来模拟string类

    1. #include <iostream>
    2. #include "string.h"
    3. class string
    4. {
    5. private:
    6.    char *str;
    7.    int len;
    8. public:
    9.     string(const char *p=0)
    10.     {
    11.       if(p!=NULL)
    12.       {
    13.        len=strlen(p);
    14.        str = new char[len];
    15.        strcpy(str,p);
    16.       }
    17.       else
    18.       {
    19.         len=0;
    20.         str = new char[1];
    21.         str[0]="\0";
    22.       }  
    23.     }
    24.     char& operator [](int i)
    25.     {
    26.     return str[i];
    27.     }
    28.     int length()
    29.     {
    30.      return len;
    31.     }
    32. };
    33. int main()
    34. {
    35.        string s="SAD";
    36.        for(int i=0;i< s.length();i++)
    37.        std::cout << s[i] << std::endl;
    38.        return 0;
    39. } 
    复制代码


    运行打印:

    1. S
    2. A
    3. D
    复制代码


     
    函数对象

    函数对象是指该对象具备函数的行为
    函数对象,是通过()调用操作符声明得到的,然后便能通过函数方式来调用该对象了.
    ()调用操作符可以定义不同参数的多个重载函数
    ()调用操作符只能通过类的成员函数重载(不能通过全局函数)
    函数对象用于在工程中取代函数指针

    比如,定义一个函数对象t:

    1. class Test{
    2. public:
    3.       void operator () (void)  //通过()重载操作符,来使对象具备函数的行为
    4.      {
    5.               cout<<"hello"<<endl;
    6.      }
    7. };
    8. int main()
    9. {
    10.        Test t;
    11.        t();          //打印"hello"
    12. } 
    复制代码


    &nbsp;
    函数对象与普通函数区别
    函数对象
    可以封装自己的成员以及其它函数,所以能够更好的面向对象.
    普通函数
    往往只具备逻辑关系,并且没有固定的成员,因为普通函数一被调用完后,里面的内容便被摧毁了,除非使用全局变量,但是全局变量又不具备封装性.
    接下来,我们来个普通函数和函数对象的示例,便知道两者的区别了.
    需求如下:

    通过一个函数,来获取斐波那契数列每项的值
    每调用一次函数,便返回一个值
    可以重复使用

    普通函数实例:

    1. #include <iostream>           
    2. using namespace std;
    3. int cnt0=0;
    4. int cnt1=1;
    5. void fib_set(int n)          //设置斐波那契数列为哪一项,使fib()能重复使用
    6. {
    7.      cnt0=0;
    8.      cnt1=1;
    9.      for(int i=0;i<n;i++)
    10.      {
    11.             int tmp=cnt1;
    12.             cnt1=cnt0+cnt1;
    13.             cnt0=tmp;
    14.      }
    15. }
    16. int fib()              //计算出一项值
    17. {
    18.   int tmp=cnt1;
    19.   cnt1=cnt0+cnt1;
    20.   cnt0=tmp;
    21.   return tmp;
    22. }
    23. int main()
    24. {
    25.   for(int i=0;i<5;i++)
    26.   cout<<fib()<<endl;    //打印1~5项值
    27.   fib_set(0);                  //从新设置项数位0
    28.   for(int i=0;i<5;i++)
    29.   cout<<fib()<<endl;    //再次打印1~5项值,使它能重复使用
    30.   return 0;     
    31. } 
    复制代码


    运行打印:

    1. 1
    2. 1
    3. 2
    4. 3
    5. 5
    6. 1
    7. 1
    8. 2
    9. 3
    10. 5
    复制代码


    从上面代码可以看到,通过普通函数实现的需求,还需要两个全局变量才行,这在大项目里,完全不可取的,若项目里,像这样的模块多的话,那得有多少个全局变量啊?并且这些全局变量能够随意被破坏,没有一点封装性.
    &nbsp;
    接下来,通过函数对象来完成这个需求:

    1. #include <iostream>           
    2. using namespace std;
    3. class Fib{
    4. private:
    5.        int cnt0;
    6.        int cnt1;
    7. public:
    8.        Fib(int n=0)
    9.        {
    10.           cnt0=0;
    11.           cnt1=1;
    12.        }
    13.        void operator =(int n)
    14.        {
    15.           cnt0=0;
    16.           cnt1=1;      
    17.           for(int i=0;i<n;i++)
    18.           {
    19.              int tmp=cnt1;
    20.              cnt1+=cnt0;
    21.              cnt0=tmp;
    22.           }
    23.        }
    24.        int operator () ()
    25.        {
    26.              int tmp=cnt1;
    27.              cnt1+=cnt0;
    28.              cnt0=tmp;
    29.               return cnt0;
    30.        }
    31. };
    32. int main()
    33. {
    34.   Fib  fib;
    35.   for(int i=0;i<5;i++)
    36.   cout<<fib()<<endl;    //打印1~5项值
    37.   fib=0;                        //从新设置项数为0
    38.   for(int i=0;i<5;i++)
    39.   cout<<fib()<<endl;    //打印1~5项值
    40.   return 0;     
    41. } 
    复制代码


    运行打印:

    1. 1
    2. 1
    3. 2
    4. 3
    5. 5
    6. 1
    7. 1
    8. 2
    9. 3
    10. 5
    复制代码


    从上面代码看到,使用函数对象后,便不需要使用全局变量了.
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-21 15:39 , Processed in 0.386099 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表