zoukankan      html  css  js  c++  java
  • 函数指针和函数对象

    函数指针(全局函数/类成员函数)、函数对象(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)
    // 本文转自 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)

    http://blog.csdn.net/adcxf/article/details/3969717

  • 相关阅读:
    Mysql 库表
    Mysql (二)
    SQLAlchemy
    Mysql 测试题
    jquery
    抽屉 演示
    前端项目
    JavaScript
    Html Css  练习
    Pandas之DataFrame——Part 3
  • 原文地址:https://www.cnblogs.com/findumars/p/5355989.html
Copyright © 2011-2022 走看看