8、泛型程序设计与c++标准模板库5.函数对象

1、函数对象

函数对象是STL提供的第四类主要组件,它使得STL的应用更加灵活方便,从而增强了算法的通用性。大多数STL算法可以用一个函数对象作为参数。所谓“函数对象”其实就是一个行为类似函数的对象,它可以不需要参数,也可以带有若干参数,其功能是获取一个值,或者改变操作的状态。

在c++程序设计中,任何普通的函数和任何重载了调用运算符operator()的类的对象都满足函数对象的特征,因此都可以作为函数对象传递给算法作为参数使用。

以数值算法accumulate()为例子,介绍函数对象的设计及应用过程。

数值算法accumulate()的调用格式包括两种:第一种调用格式是以"+"运算符作为运算规则,第二种算法允许用户铜鼓哦传递给算法相应的函数对象来指定计算规则。

一般来说,用户设计的普通函数就是一种最简单的函数对象,

例子1:利用普通函数来定义函数对象

#include<iostream>

#include<numeric>  //包含数值算法头文件

using namespace std;

int mutl(int x, int y)

{ return x + y; }//定义一个普通函数

int main() {

int A[] = {1,2,3,4,5};

const int N = sizeof(A) / sizeof(int);

cout << "The result by multipling all elements in A is"   << accumulate(A, A + N, 1, mutl);

getchar();

cout<<endl;//将普通函数mutl传递给通用算法

}

除了普通函数,另一类函数对象可以是类的对象,并且在定义中重载函数调用运算符。

例子2:改写上面的程序

#include<iostream>

#include<numeric>  //包含数值算法头文件

using namespace std;

class multclass   //定义multclass类

{ public:

int operator()( int x, int y )const{return x*y; }//重载操作符operator()

};

int main()

{

int A[] = { 1, 2, 3, 4, 5 };

const int N = sizeof(A) / sizeof(int);

cout << "The result by multipling all elements in A is"   << accumulate(A, A + N, 1, multclass());//将类multclass传递给通用算法

getchar();

cout << endl;//将普通函数mutl传递给通用算法

}

分析:通过在类multclass中重载运算符operator(),就定义了一种可以作为函数参数的对象,同样可以像使用普通函数mutl一样来使用该对象。但是这里传递给算法accumulate的对象是通过multclass类的默认构造函数multclass()获得的,它可以由编译器自动提供。使用类的形式定义的函数对象能够比普通函数携带更多的额外信息。

除了上面之外,STL中也定义了一些标准的函数对象,如果以功能划分,可以分为算数运算、关系运算、逻辑运算三大类。为了调用这些标准函数对象,需要包含头文件<functional>。标准函数对象是内连函数。

2、函数适配器

与前面介绍过的迭代器适配器的作用类似,函数适配器也可以帮助创建种类更多的函数对象。与直接铜鼓哦结构或类定义来创建新的函数对象相比,使用函数适配器是一种更加容易的方式。

时间: 2024-12-26 08:24:05

8、泛型程序设计与c++标准模板库5.函数对象的相关文章

Part10 泛型程序设计与C++标准模板库 10.1泛型程序设计及STL的结构

1泛型程序设计的基本概念泛型程序设计: 编写不依赖于具体数据类型的程序 将算法从特定的数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 术语:概念用来界定具备一定功能的数据类型.例如: 将"可以比大小的所有数据类型(有比较运算符)"这一概念记为Comparable 将"具有公有的复制构造函数并可以用'='赋值的数据类型"这一概念记为Assignable 将"可以比大小.具有公有的复制构造函数并可以用'='赋值的所有数据类型&quo

8、泛型程序设计与c++标准模板库2.3双端队列容器

双端队列容器是一种放松了访问权限的队列.除了从队列的首部和尾部访问元素外,标准的双端队列也支持通过使用下标操作符"[]"进行直接访问. 它提供了直接访问和顺序访问方法.其头文件为<deque>. 1)双端队列容器的构造函数 有4中形式的构造函数: deque();//构造size()为0的双端队列容器 deque(size_type n,const T& v=T());//初始化大小为n的双端队列,第二个参数是每个元素的初始值,默认为T()构造的对象 deque(c

8、泛型程序设计与c++标准模板库2.4列表容器

列表容器主要用于存放链表,其中的链表是双向链表,可以从任意一端开始遍历.列表容器是需要按顺序访问的容器.另外,列表容器不支持随机访问迭代器,因此某些算法不能适合于列表容器.列表容器还提供了另一种操作---拼接(splicing),其作用是将一个序列中的元素插入到另一个序列中.其头文件为<list> 1.列表容器的构造函数 4种形式的构造函数: list();//构造size()为0的列表容器 list(sizt_type n,const T& v=T());//初始化一个大小为n的列表

Part10 泛型程序设计与C++标准模板库 10.7算法

STL算法本身是一种函数模版 通过迭代器获得输入数据 通过函数对象对数据进行处理 通过迭代器将结果输出STL算法是通用的,独立于具体的数据类型.容器类型 STL算法分类 不可变序列算法 可变序列算法 排序和搜索算法 数值算法 不可变序列算法 不直接修改所操作的容器内容的算法 用于查找指定元素.比较两个序列是否相等.对元素进行计数等例: template<class InputIterator, class UnaryPredicate> InputIterator find_if(InputI

PKU C++程序设计实习 学习笔记6 标准模板库STL

标准模板库STL 8.1 STL概述 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用:1.面向对象的思想:继承和多态,标准类库  2.泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库 STL 简单地说就是使用模板的程序设计法. 将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法. 标准模

八、C++ 标准模板库-STL概述

C++ 标准模板库-STL概述 一.基本概念 1.1 泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用,重用在两个方面有体现: 面向对象的思想:继承和多态,标准类库 泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库 STL 简单地说就是使用模板的程序设计法.将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法. 标准模板库

标准模板库--STL

标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库STL 简单地说就是使用模板的程序设计法. 将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法.标准模板库 (Standard

C++ 标准模板库介绍(STL)

1. STL 基本介绍 C++ STL(标准模板库)是惠普实验室开发的一系列软件的统称,是一套功能强大的 C++ 模板类.STL的目的是为了标准化组件,这样就不用重新开发,让后来者可以使用现成的组件,和开源组件有点殊途同归. STL的版本很多,常见的有HP STL.PJ STL. SGI STL等,另外,STL库属于C++标准库的一部分,两者是包含关系. 由于我平时的编程环境主要在Linux系统下,所以在后面总结中,我会主以GNU ISO C++ Library中的STL源码(5.2.1版本)为

C++ Primer 学习笔记_13_标准模板库_list双向链表容器

C++ Primer 学习笔记_13_标准模板库_list双向链表容器 list容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入.删除和查找都是超快速的.下图是双向循环链表的结构示意图. list的每个节点有三个域:前驱元素指针域.数据域和后继元素指针域.前驱元素指针域保存了前驱元素的首地址:数据域则是本节点的数据:后继元素指针域则保存了后继元素的首地址.list的头结点的前驱元素指针域保存的是链表中尾元素的首地址,而list的尾