函数指针(全局函数/类成员函数)和函数对象

来源:互联网 发布:java高级程序设计下载 编辑:程序博客网 时间:2024/06/10 09:47
一. 函数指针类型为全局函数.#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)// 本文转自 C++Builder研究 - http://www.ccrun.com/article.asp?i=1005&d=sc37og#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)

原创粉丝点击