C++超详细讲解函数对象

目录
  • 一、客户需求
  • 二、存在的问题
  • 三、解决方案
  • 四、函数对象
  • 五、小结

一、客户需求

编写一个函数

  1. 函数可以获得斐波那契数列每项的值
  2. 每调用一次返回一个值
  3. 函数可根据需要重复使用

下面来看第一个解决方案:

#include <iostream>
using namespace std;
int fib()
{
    static int a0 = 0;
    static int a1 = 1;
    int ret = a1;
    a1 = a0 + a1;
    a0 = ret;
    return ret;
}
int main()
{
    for (int i = 0; i < 10; i++)
    {
        cout << fib() << endl;
    }
    cout << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << fib() << endl;
    }
    return 0;
}

输出结果如下:

二、存在的问题

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

  • 静态局部变量处于函数内部,外界无法改变
  • 函数为全局函数,是唯一的,无法多次独立使用
  • 无法指定某个具体的数列项作为初始值

三、解决方案

函数对象

  • 使用具体的类对象取代函数
  • 该类的对象具备函数调用的行为
  • 构造函数指定具体数列项的起始位置
  • 多个对象相互独立的求解数列项

四、函数对象

函数调用操作符(( ))

  • 只能通过类的成员函数重载
  • 可以定义不同参数的多个重载函数

所以最终解决方案如下:

#include <iostream>
using namespace std;
class Fib
{
    int a0;
    int a1;
public:
    Fib()
    {
        a0 = 0;
        a1 = 1;
    }
    Fib(int n)
    {
        a0 = 0;
        a1 = 1;
        for (int i = 2; i <= n; i++)
        {
            int t = a1;
            a1 = a0 + a1;
            a0 = t;
        }
    }
    int operator () ()
    {
        int ret = a1;
        a1 = a0 + a1;
        a0 = ret;
        return ret;
    }
};
int main()
{
    Fib fib;
    for (int i = 0; i < 10; i++)
    {
        cout << fib() << endl;
    }
    for (int i = 0; i < 5; i++)
    {
        cout << fib() <<endl;
    }
    cout << endl;
    Fib fib2(10);
    for (int i = 0; i < 5; i++)
    {
        cout << fib2() << endl;
    }
    return 0;
}

输出结果如下:

五、小结

  • 函数调用操作符(( ))是可重载的
  • 函数调用操作符只能通过类的成员函数重载
  • 函数调用操作符可以定义不同参数的多个重载函数
  • 函数对象用于在工程中取代函数指针

到此这篇关于C++超详细讲解函数对象的文章就介绍到这了,更多相关C++函数对象内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++中的函数指针与函数对象的总结

    篇一.函数指针函数指针:是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址. 函数指针的用途是很大的,主要有两个作用:用作调用函数和做函数的参数. 函数指针的声明方法:数据类型标志符 (指针变量名) (形参列表):一般函数的声明为: int func ( int x );而一个函数指针的声明方法为:int (*func) (int x);前面的那个(*func)中括号是必要的,这会告诉编译器我们声明的是函数指针而不是声明一个具有返回型为指针

  • C++函数对象详解附带实例

    如果一个类将()运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象.函数对象是一个对象,但是使用的形式看起来像函数调用,实际上也执行了函数调用,因而得名. 下面是一个函数对象的例子. #include <iostream> using namespace std; class CAverage { public: double operator()(int a1, int a2, int a3) { //重载()运算符 return (double)(a1 + a2 + a

  • C++:函数对象,STL提供的函数对象,函数适配器详解

    目录 1 函数对象 2 STL提供的函数对象 3 函数适配器 总结 1 函数对象 1.函数对象是行为类似函数的对象.一个类对象,表现出一个函数的特征,即通过对象名+(参数列表)的方式使用一个类对象. 2.使用STL中提供的或自定义的迭代器和**函数对象,**配合STL的算法,组合出各种各样的功能. 3.通过函数对象而不使用函数指针,可以增加通用性,提高效率. 4.函数对象概念:泛化的函数 ①将普通函数作为函数对象:传递函数名 #include <iostream> #include <n

  • 一起来学习C++的函数指针和函数对象

    目录 函数指针 函数对象 总结 函数指针 以下是<cstdlib>库中的一个排序数组的方法qsort()的函数原型. void qsort (void* base, size_t num, size_t size, int (*compar)(const void*, const void*)); base -- 指向要排序的数组的第一个元素的指针. num -- 由 base 指向的数组中元素的个数. size -- 数组中每个元素的大小,以字节为单位. compar -- 用来比较两个元素

  • 如何应用C++的函数对象

    前言 C++函数对象是通过一张虚函数表来实现的.简称为V-Table.在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承.重载的问题,保证其容真实反应实际的函数. 应用 假如我们实现了这样的一个单向链表: class LinkedListNode { int data_; LinkedListNode *next_; }; class LinkedList { public: void insert(LinkedListNode* &p); void del(LinkedListNode

  • C++超详细讲解函数对象

    目录 一.客户需求 二.存在的问题 三.解决方案 四.函数对象 五.小结 一.客户需求 编写一个函数 函数可以获得斐波那契数列每项的值 每调用一次返回一个值 函数可根据需要重复使用 下面来看第一个解决方案: #include <iostream> using namespace std; int fib() { static int a0 = 0; static int a1 = 1; int ret = a1; a1 = a0 + a1; a0 = ret; return ret; } in

  • C语言超详细讲解函数栈帧的创建和销毁

    目录 1.本节目标 2.相关寄存器 3.相关汇编指令 4.什么是函数栈帧 5.什么是调用堆栈 6.函数栈帧的创建和销毁 (1).main函数栈帧的创建与初始化 (2).main函数的核心代码 (3).Add函数的调用过程 (4).Add函数栈帧的销毁 (5).调用完成 7.对开篇问题的解答 1.本节目标 C语言绝命七连问,你能回答出几个? 局部变量是如何创建的?为什么局部变量不初始化其内容是随机的?有些时候屏幕上输出的"烫烫烫"是怎么来的?函数调用时参数时如何传递的?传参的顺序是怎样的

  • C++超详细讲解函数参数的默认值

    目录 1.参数默认值的指定方式 2.参数默认值的指定规则 1.参数默认值的指定方式 在 C++ 中,可以在函数声明时为参数提供一个默认值.这样在函数调用时,如果没有提供函数参数值,则使用默认值. e.g. 在函数声明时,指定参数默认值 void Demo(int x = 0); int main(int argc, char* argv[]) { Demo(); // 不用提供参数,会将 x = 0 的结果输出 return 0; } void Demo(int x) { printf("x =

  • C++超详细讲解函数重载

    目录 1 函数重载的定义 2 构成函数重载的条件 3 编译器调用重载函数的准则 4 函数重载的注意事项 4.1 避开重载带有指定默认值参数的函数 4.2 注意函数重载遇上函数指针 4.3 C++编译器不能以 C 的方式编译重载函数 1 函数重载的定义 函数重载:使用同一个函数名定义不同的函数.从本质上来看,就是互相独立的不同函数,每一个函数类型不同.因此,函数重载是由函数名和参数列表决定的. 注意:函数返回值不能作为函数重载的重要依据! 2 构成函数重载的条件 当满足以下三个条件之一时,便可以构

  • C语言超详细讲解函数指针的运用

    目录 前言 计算器的例子 回调函数 转移表 前言 前面我们学习了各种各样的指针类型,有些指针可以说是稀奇百怪,特别是函数指针,有些朋友可能觉得,函数指针有些多余,调用函数为什么要用指针调用,直接调用不好吗? 接下来我们从具体的实例来回答同学们的问题,加深对函数指针的理解. 计算器的例子 接下来我们写一个简单的计算器程序,完成不同的计算功能比如加减乘除: #include <stdio.h> //相加函数 int add(int a, int b) { return a + b; } //相减函

  • Java 超详细讲解对象的构造及初始化

    目录 如何初始化对象 构造方法 特性 默认初始化 就地初始化 如何初始化对象 我们知道再Java方法内部定义一个局部变量的时候,必须要初始化,否则就会编译失败 要让这串代码通过编译,很简单,只需要在正式使用a之前,给a设置一个初始值就好那么对于创造好的对象来说,我们也要进行相对应的初始化我们先写一个Mydate的类 public class MyDate { public int year; public int month; public int day; /** * 设置日期: */ pub

  • C语言函数超详细讲解下篇

    目录 前言 函数的声明和定义 函数声明 函数定义 举例 简单的求和函数 把加法单独改写成函数 添加函数声明 带头文件和函数声明 静态库(.lib)的生成 静态库文件的使用方法 函数递归 什么是递归? 递归的两个必要条件 练习1 一般方法 递归的方法 练习2 一般方法 递归方法 练习3 一般方法 递归方法 练习4 一般方法 递归方法 递归与迭代 递归隐藏的问题 如何改进 选递归还是迭代 总结 前言 紧接上文,继续学习函数相关内容. 函数的声明和定义 函数声明 告诉编译器有一个函数叫什么,参数是什么

  • Java Scala数据类型与变量常量及类和对象超详细讲解

    目录 一.数据类型 二.变量和常量 三.类和对象 3.1 类 3.2 对象 3.3 伴生类和伴生对象 3.4 Scala的main函数只能写在object里 总结 一.数据类型 简记: 所有基础类型基本与Java的包装类等同,唯一有不同的Int(Scala),Integer(Java),注意这个就好 Unit, Null, Nothing, Any, AnyRef, AnyVal,这几个除了Null乍一眼会有些陌生,不要怕,上总结: 首先是层级图: 然后是表格: 补丁: 记住Any是所有类型的超

  • Java 超详细讲解类的定义方式和对象的实例化

    目录 1.面对对象的初步认识 1.1什么是面向对象 1.2面向对象与面向过程 2.类的定义与使用 2.1简单认识类 2.2 类的定义格式 3.类的实例化 3.1什么是实例化? 3.2重点笔记 总结 1.面对对象的初步认识 1.1什么是面向对象 用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序的设计.扩展以及维护都非常友好. 1.2面向对象与面向过程 举一个买手机的例子 以面向对象的方式来处理买手机这件事的话,我们就不需要关注买手机的过程,具体手机怎么买,如何到手,用户不用去关心,

  • C语言函数超详细讲解上篇

    目录 前言 1.函数是什么? 2.C语言中函数的分类 2.1 库函数 2.1.1 如何学会使用库函数 2.1.2 自定义函数 3.函数的参数 3.1 实际参数(实参) 3.2 形式参数(形参) 4.函数的调用 4.1 传值调用 4.2 传址调用 4.3 练习 4.3.1 判断一个数是不是素数 4.3.2 判断一年是不是闰年 4.3.3 二分查找 4.3.4 数值自增增加1 5.函数的嵌套调用和链式访问 5.1 嵌套调用 5.2 链式访问 总结 前言 本文主要学习函数的相关内容. 1.函数是什么?

随机推荐