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

 更新时间:2016年08月14日 08:59:37   投稿:daisy  
C++函数对象是C语言程序的主要组成部分,一个函数可以调用其他函数。在设计良好的程序中,每个函数都有特定的目的。本文将介绍C++函数对象的应用,有需要的可以参考学习。

前言

C++函数对象是通过一张虚函数表来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、重载的问题,保证其容真实反应实际的函数。

应用

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

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

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

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

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

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

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

我们可以这样:

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

总结

以上就是C++函数对象的应用的全部内容,希望本文的内容对大家学习C++的函数对象能有所帮助,如果有疑问欢迎大家留言讨论。

相关文章

  • 教你用C语言实现三子棋

    教你用C语言实现三子棋

    这篇文章主要为大家详细介绍了C语言实现简单三子棋程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C语言新手练习题之求第n个斐波那契数

    C语言新手练习题之求第n个斐波那契数

    斐波那契数列这一个大一上C语言就有的问题大家应该都不陌生,下面这篇文章主要给大家介绍了关于C语言新手练习题之求第n个斐波那契数的相关资料,文中通过图文以及实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • Qt实现边加载数据边显示页面的示例代码

    Qt实现边加载数据边显示页面的示例代码

    无论是MFC框架还是QT框架,实现加载数据的等待效果都是很麻烦的,不像WEB端轻轻松松一句代码就搞定了。本文将通过Qt实现边加载数据边显示页面的功能,需要的可以参考一下
    2022-01-01
  • opencv3/C++实现光流点追踪

    opencv3/C++实现光流点追踪

    今天小编就为大家分享一篇opencv3/C++实现光流点追踪,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • 深入探究C++编程中的资源泄漏问题以及排查方法

    深入探究C++编程中的资源泄漏问题以及排查方法

    在C++程序开发维护过程中,时常会遇到资源泄漏问题,比如GDI对象泄漏、进程线程句柄泄漏以及内存泄漏问题,今天我们就来深入探讨一下这几类资源泄漏以及排查这些泄露的办法,需要的朋友可以参考下
    2023-10-10
  • C++ Boost Thread线程使用示例详解

    C++ Boost Thread线程使用示例详解

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • C++ boost scoped_ptr智能指针详解

    C++ boost scoped_ptr智能指针详解

    智能指针是一种像指针的C++对象,但它能够在对象不使用的时候自己销毁掉。虽然STL提供了auto_ptr,但是由于不能同容器一起使用(不支持拷贝和赋值操作),因此很少有人使用。它是Boost各组件中,应用最为广泛的一个
    2022-11-11
  • C语言中时间的基本用法小结

    C语言中时间的基本用法小结

    处理时间是编程中经常遇到的问题,C语言中提供了一些时间处理函数,在此记录下一些基本的用法。下面这篇文章主要给大家介绍了C语言中关于时间的基本用法的相关资料,需要的朋友可以参考借鉴,感兴趣的朋友们来一起看看吧。
    2017-01-01
  • C++快速幂与大数取模算法示例

    C++快速幂与大数取模算法示例

    这篇文章主要介绍了C++快速幂算法和大数取模算法的示例,对C++程序员来说有一定的帮助,有需要的朋友可以参考借鉴,下面来一起看看。
    2016-08-08
  • 汇编语言rep movsd 的使用详解

    汇编语言rep movsd 的使用详解

    rep movsd 每次ecx!=0便执行movsd ,然后ecx=ecx-1 movsd移动ds:[si] 到es:[di],在32位汇编下可以用esi代替si,edi代替di
    2013-09-09

最新评论