回调给班级成员

时间:2012-12-16 19:53:13

标签: c++ callback

我正在尝试构建一个非常简单的调度程序。它允许将任务(函数)添加到列表中并按设定的时间间隔运行。如果我提供一个静态函数作为其'ScheduleTask'成员的参数,'Scheduler'类可以正常工作。

class TestController
{
private:
    Scheduler _scheduler;

public:
    TestController(void)
    {
        _scheduler.ScheduleTask(Task1, 3000);
        _scheduler.ScheduleTask(Task2, 5000);
    }
    ~TestController(void);

    void Task1(void) { }
    void Task2(void) { }
};

struct Task
{
    long interval;
    long last_run;
    void (*TaskCallback) (void);

    Task()
    {
        last_run = 0;
    }
};

class Scheduler
{
private:
    std::vector<Task> _tasks;
public:
    Scheduler(void) { }
    ~Scheduler(void) { }

    void ScheduleTask(void (*TaskCallback) (void), long interval)
    {
        Task t;
        t.TaskCallback = TaskCallback;
        t.interval = interval;
        _tasks.push_back(t);
    }

    void loop()
    {
        for(unsigned int i = 0; i < _tasks.size(); i++)
        {
            long elapsed = clock();

            if(elapsed - _tasks[i].last_run >= _tasks[i].interval)
            {
                _tasks[i].last_run = elapsed;
                _tasks[i].TaskCallback();
            }
        }
    }

};

如何修改回调以接受已经实例化的'TestController'对象上的成员?

1 个答案:

答案 0 :(得分:1)

使用boost::functionboost::bind的组合。或者,如果您的编译器支持它们,请使用std::functionstd::bind

#include <boost/bind.hpp>
#include <boost/function.hpp>

#include <vector>

typedef boost::function<void()> Callback;

struct Task
{
    long interval;
    long last_run;
    Callback TaskCallback;

    Task()
    {
        last_run = 0;
    }
};

class Scheduler
{
private:
    std::vector<Task> _tasks;
public:
    Scheduler(void) { }
    ~Scheduler(void) { }

    void ScheduleTask(const Callback& TaskCallback, long interval)
    {
        Task t;
        t.TaskCallback = TaskCallback;
        t.interval = interval;
        _tasks.push_back(t);
    }

    void loop()
    {
        for(unsigned int i = 0; i < _tasks.size(); i++)
        {
            long elapsed = clock();

            if(elapsed - _tasks[i].last_run >= _tasks[i].interval)
            {
                _tasks[i].last_run = elapsed;
                _tasks[i].TaskCallback();
            }
        }
    }
};

class TestController
{
private:
    Scheduler _scheduler;

public:
    TestController(void)
    {
        _scheduler.ScheduleTask(boost::bind(&TestController::Task1,this), 3000);
        _scheduler.ScheduleTask(boost::bind(&TestController::Task2,this), 5000);
    }
    ~TestController(void);

    void Task1(void) { }
    void Task2(void) { }
};