首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > 函数指针(全局函数/类成员函数)、函数对象(Function object)
【标  题】:函数指针(全局函数/类成员函数)、函数对象(Function object)
【关键字】:Function,object
【来  源】:http://www.cppblog.com/erran/archive/2006/12/26/16868.html

函数指针(全局函数/类成员函数)、函数对象(Function object)

C++博客 - Welcome to ErranLi's Blog! - 函数指针(全局函数/类成员函数)、函数对象(Function object)
C++博客 首页 新随笔 联系 聚合 管理
  23 Posts :: 0 Stories :: 9 Comments :: 0 Trackbacks

一.?? 函数指针类型为全局函数 .

?

?

#include "stdafx.h"

?

#include <iostream>

using namespace std;

?

class TestAction;

?

typedef void (*fp)(int);

?

void Drink(int i)

{

?????? cout<<"No. "<<i<<" drink..."<<endl;

}

?

void Eat(int i)

{

?????? cout<<"No. "<<i<<" eat..."<<endl;

}

?

class TestAction

{

public:

?????? fp testAct;

?

?????? void TestAct(int i)

?????? {

????????????? if (testAct != NULL)

????????????? {

???????????????????? testAct(i);

????????????? }

?????? }

};

?

int main(int argc, char* argv[])

{????

?????? TestAction doact;

?????? doact.testAct = &Drink;?????

?????? doact.TestAct(0);

?????? doact.TestAct(1);

?????? doact.TestAct(2);

?????? doact.testAct = &Eat;?

?????? doact.TestAct(0);

?????? doact.TestAct(1);

?????? doact.TestAct(2);

?????? return 0;

}

?

?

二.?? 函数指针类型为类成员函数 .

?

#include "stdafx.h"

?

#include <iostream>

using namespace std;

?

class Action;

class TestAction;

?

// 函数指针类型为类 Action 的成员函数

typedef void (Action::*fp)(int);

?

class Action

{

public:

?????? void Drink(int i)

?????? {

????????????? cout<<"No. "<<i<<" drink..."<<endl;

?????? }

?

?????? void Eat(int i)

?????? {

????????????? cout<<"No. "<<i<<" eat..."<<endl;

?????? }

};

?

class TestAction

{

public:

?????? // 定义一个函数指针

?????? fp testAct;

?????? //Action 对象实例 , 该指针用于记录被实例化的 Action 对象

?????? Action * pAction;

?

?????? void TestAct(int i)

?????? {

????????????? if ((pAction != NULL) && (testAct != NULL))

????????????? {

???????????????????? // 调用

????????????? ?????? (pAction->*testAct)(i);

????????????? }

?????? }

};

?

int main(int argc, char* argv[])

{

?????? Action act;

?????? TestAction doact;

?????? doact.pAction = &act;

?????? doact.testAct = Action::Drink;??

?????? doact.TestAct(0);

?????? doact.TestAct(1);

?????? doact.TestAct(2);

?????? doact.testAct = Action::Eat;?????

?????? doact.TestAct(0);

?????? doact.TestAct(1);

?????? doact.TestAct(2);

?????? return 0;

}

?

?

?

三.?? 函数对象 (Function object)

?

#include "stdafx.h"

?

#include <iostream>

#include <functional>

?

using namespace std;

?

class Action;

class Drink;

class Eat;

class TestAction;

?

class Action

{

public:???

?????? int operator()(int i)

?????? {

????????????? Act(i);

????????????? return i;

?????? }

?

?????? virtual void Act(int i) = 0;

};

?

class Drink : public Action

{

?????? void Act(int i)

?????? {

????????????? cout<<"No. "<<i<<" drink..."<<endl;

?????? }

};

?

class Eat : public Action

{

?????? void Act(int i)

?????? {

????????????? cout<<"No. "<<i<<" eat..."<<endl;

?????? }????

};

?

class TestAction

{

public:

?????? void TestAct(int i, Action& testAct)

?????? {????

????????????? testAct(i);

?????? }

};

?

int main(int argc, char* argv[])

{???????????

?????? TestAction doact;??????????????

?????? doact.TestAct(0, Drink());

?????? doact.TestAct(1, Drink());

?????? doact.TestAct(2, Drink());??

?????? doact.TestAct(0, Eat());

?????? doact.TestAct(1, Eat());

?????? doact.TestAct(2, Eat());

?????? return 0;

}

?

虽然传递函数指针被广泛应用于事件驱动系统中,以此实现回调函数通过指针来调用。但 C++ 还是提供了另外一种可供选择的办法,即函数对象,利用它可以避免使用函数指针。这样做有几个优点。首先, 因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用结果的数据成员。。 此外,编译器可以内联函数对象,从而进一步增强性能。函数对象可以具体表达依赖成员模板的通用算法 , 这些算法借助普通的函数指针难以完成。例用函数对象实现了一个通用的 Negation 算法操作:

#include "stdafx.h"

?

#include <iostream>

?

using namespace std;

?

class Negate

{

public:

?????? template<class T> T operator()(T t) const

?????? {

????????????? return -t;

?????? }

};

?

void Callback(int n, const Negate& neg)? // 传递一个函数对象

{

?????? n = neg(n);? // 调用重载的 () 操作 来对 n 进行 negate 操作

?????? cout << n << endl;

}

?

int main(int argc, char* argv[])

{

?????? // 调用方式一

?????? Callback(5, Negate());

?

?????? // 调用方式二

?????? Negate neg;

?????? cout << neg(9.99999) << endl;??????

?????? cout << neg(__int32(39999999)) << endl;

???

?????? return 0;

}

?

?????? STL 库中定义了很多函数对象以供相关算法调用,如 模板化的函数对象 greater<> 或者 less<>:

?

vector <int> vi;
//..
填充向量

sort(vi.begin(), vi.end(), greater<int>() );//
降序 (descending)
sort(vi.begin(), vi.end(), less<int>() ); //
升序
(ascending)

?

All Test pass[VC6.0]

posted on 2006-12-26 13:27 erran 阅读(67) 评论(1)  编辑 收藏 收藏至365Key
该死的ExecuteScalar:【上一篇】
硬件兼容性的陷阱,DrawIndexedPrimitiveUP的用法:【下一篇】
【相关文章】
  • 通过IViewObject接口,取浏览器的图象,实现SNAP
  • array as one of function parameters test
  • 漫谈Java(三)-- Object的使用
  • 【翻译】Object relational persistence in .Net
  • Delphi中通过CreateObject创建的 COM 对象如何获取事件
  • 浅出理解静态成员函数(static member function)
  • Asp.net 2.0 使用FormView + ObjectDataSource 或 SqlDataSource 插入记录后 定位到被插入行
  • Asp.Net22.0中ObjectDataSource+Formview实现添加,修改
  • How to find function module or Bapi for particular
  • Using the XML HTTP Request object----ajax读书笔记(二)
  • 【随机文章】
  • Win32 ASM详解-超类化
  • 如何满屏播放AVI文件
  • 互联网上的网络时间服务器地址
  • C++中协程的实现
  • 佛经上181条做人的道理箴言[转]
  • 如何申请Gmail免费企业邮局
  • 演练:使用 Visual C# 创作简单的多线程组件
  • Maya 4.0 骨骼动画-创建骨骼
  • 关闭端口详解--防黑必备(包括关闭2000/xp默认共享)
  • 为“分区魔术师”加速
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.