C++函数对象的应用

假如我们实现了这样的一个单向链表:

class LinkedListNode
{
  int data_;
  LinkedListNode *next_;
};
class LinkedList
{
  public:
    void insert(LinkedListNode* &p);
    void del(LinkedListNode *p);
  private:
    LinkedListNode *head_;
};

其中insert将p插入到head_为头指针的链表中,而p对应的内存由外面分配好,调用的时候类似于这样:

LinkedList list;
LinkedListNode *p = new LinkedListNode(2, NULL);
list.insert(p);

其中,p可能是通过new得到,也可能是malloc出来。好,问题来了:

这个类的del函数应该如何实现呢?如果节点是new出来的,我们得delete;如果是malloc出来的,我们得使用配套的free。否则,行为就是undefined。而且,用户还可能实现了自己的定制的内存分配回收例程。我们并不知道该内存是如何分配得到的。这就是问题所在。

解决方法是让用户将正确的、对应的、适配的资源释放例程传递进来,然而delete是expression,free是函数,更悲剧的是不同用户实现的资源回收函数原型不尽相同。如何做呢?函数对象是解决这个问题的利器。我们可以这样:

template<typename CallBack>
class LinkedList
{
  public:
    void insert(LinkedListNode* &p);
    void del(LinkedListNode *p);
  private:
    LinkedListNode *head_;
};

在del中:

void del(LinkedListNode *p)
{
  //...
  LinkedListNode *prev = get_prev(p);
  prev->next_ = p->next_;
  CallBack cb;
  cb(p);//调用用户提供的资源回收例程
}

用户需要实现自己的CallBack类的operator()成员函数。如下所示:

class MyReclaimRoutine
{
  public:
    void operator() (LinkedListNode *p)
    {
      delete p; //free(p) ? my_release_func(p) ? all up to you!
    }
};

然后就万事大吉了:

LinkedList<MyReclaimRoutine> list;
LinkedListNode *p = new LinkedListNode(2, NULL);
list.insert(p);
list.del(p);//ok! delete p will be called

关于程序设计基石与实践更多讨论与交流,敬请关注本博客和新浪微博songzi_tea

时间: 2024-10-27 08:46:50

C++函数对象的应用的相关文章

C++中的函数对象(一)

STL中的函数对象,大多数STL类属算法(以及某些容器类)可以以一个函数对象作为参数.引入函数对象的目的是为了使算法的功能富于变化,从而增强算法的通用性. 所谓函数对象,是指一段代码实体,它可以不带参数,也可以带有若干参数,其功能是获得一个值,或者改变操作的状态.在C++编程中,任何普通的函数都满足这个定义,而且,任何一个重载了运算符operator()的类的对象也都满足这一定义,称为函数对象. 普通函数 int multfun(int x, int y) { return x*y; } 或者下

python--函数的返回值、函数参数的使用、名称空间与作用域、函数嵌套、函数对象

今天学习内容有函数的返回值.函数参数的使用.名称空间与作用域.函数嵌套. 下来我们一一查看. 函数的返回值 看几个栗子: def func(x): return x**2 y=func(10) print(y) def foo(): return None res=foo() print(res) def foo(): return{'a':1} res=foo() print(res['a']) def foo(): return {'a':1},1,'a',[1,2] res=foo() p

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

STL算法设计理念 - 函数对象和函数对象当參数和返回值

函数对象: 重载函数调用操作符的类.其对象常称为函数对象(function object),即它们是行为类似函数的对象. 一个类对象,表现出一个函数的特征,就是通过"对象名+(參数列表)"的方式使用一个类对象,假设没有上下文,全然能够把它看作一个函数对待. 这是通过重载类的operator()来实现的. "在标准库中.函数对象被广泛地使用以获得弹性".标准库中的非常多算法都能够使用函数对象或者函数来作为自定的回调行为: demo #include <iostr

谓词函数、函数对象

从概念上讲,函数对象用作函数的对象:但是从实现上来说,函数对象时实现了 operate()的类的对象. 虽然函数和函数指针也可以归为函数对象,但实现了operate()的类的对象才能保存状态,才能用于STL. 我们直接看定义: 一元函数:接受一个参数的函数,如f(x). 一元谓词函数:如果一元函数返回一个BOOL类型的值,则该函数称为谓词. 二元函数:接受2个参数的函数,如f(x,y). 二元谓词函数:如果二元函数返回一个BOOL值,则该函数称为二元谓词. 之所以给返回布尔类型的函数对象专门命名

函数对象(仿函数 functor)

简单地说,函数对象就是一个重载了()运算符的类实例,它可以像一个函数一样使用. #include <iostream> using namespace std; class Add { public: int operator ()(const int &a, const int &b) { return (a + b); } double operator ()(const double &a, const double &b) { return (a + b

【Python】函数对象

转:作者:Vamei 出处:http://www.cnblogs.com/vamei 函数也是一个对象,具有属性(可以使用dir()查询).作为对象,它还可以赋值给其它对象名,或者作为参数传递. lambda函数 在展开之前,我们先提一下lambda函数.可以利用lambda函数的语法,定义函数.lambda例子如下: func = lambda x,y: x + y print func(3,4) lambda生成一个函数对象.该函数参数为x,y,返回值为x+y.函数对象赋给func.func

11、函数对象、函数的嵌套、名称空间与作用域

一.函数对象 函数对象,函数是第一类对象,即函数可以当做数据传递 具体特点: 1.可以被引用: 1 def foo(): 2 print('from foo') 3 4 func=foo 5 6 print(foo) 7 print(func) 8 func() 2.可以当作参数传递 1 def foo(): 2 print('from foo') 3 4 def bar(func): 5 print(func) 6 func() 7 8 bar(foo) 3.返回值可以是函数 1 def fo

python函数对象

适用于python 2.x版本 1. lambda函数 1 func = lambda x, y : x + y 2 print func(2, 4) lambda生成一个函数对象,参数是x,y, 返回x+y. 2. map() 函数 1 rtn = map((lambda x: x*3), [1, 2, 3, 4, 5, 6]) 2 print rtn map是python内置函数,第一个参数是函数,第二个参数是一个序列.第一个函数作用与序列的每一个元素,并将结果放在序列rtn里. 3. re

函数对象

函数对象也叫函数符,包括函数名.指向函数的指针和重载了()运算符的类对象.重载的()运算符将使得能够像函数那样使用类对象.如for_each()的第三个参数可以使常规函数,也可以是函数符,它将指定的函数用于区间中的每个成员. 生成器是不用参数就可以调用的函数符,一元函数是用一个参数可以调用的函数符,而返回bool值的一元函数就是谓词.返回bool类型的二元函数叫二元谓词,如sort()第三个参数就需要二元谓词,前两个参数是要STL容器要排序的迭代器.在list模板中有一个remove_if()成