函数指针(全局函数/类成员函数)、函数对象(Function object)
一. 函数指针类型为全局函数.
#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++ 还是提供了另外一种可供选 择的办法,即函数对象,利用它可以避免使用函数指针。这样做有几个优点。首 先, 因 |