在C ++中使用类模板作为回调

时间:2017-02-23 06:12:58

标签: c++ class templates c++03

我能够在没有类模板的情况下进行回调工作。但我的要求是通过传递模板形式的类对象来实现回调。我已经在main()中写了我的意图,但不知怎的,我无法使它工作。

我不能将boost和C ++ 11用于我当前的问题。任何帮助将不胜感激。

// TestProj.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "glb.h"
#include "Test.h"
#include <iostream>
using namespace std;

class MyCallBack
{
private:
    class Callback
    {
    public:
        virtual ~Callback() { }
        virtual void call() = 0;
    };

    template <typename T>
    class ClassCallback : public Callback
    {
    private:
        T*      object;
        void (T::*callback)();

    public:
        ClassCallback(T* obj, void (T::*clbk)()) : object(obj), callback(clbk) {}
        virtual void call() { (object->*callback)(); }
    };

private:
    Callback*       callback;

public:
    MyCallBack() : callback(NULL) { }
    ~MyCallBack() { delete callback; }

    template <typename T>
    MyCallBack(T* obj, void (T::*clbk)())
    {
        callback = new ClassCallback<T>(obj,clbk);
    }

    void operator () ()
    {
        callback->call();
    }
};

typedef enum {
    EVENT1 = 1,
    EVENT2 = 2,
    EVENT3 = 4,
    EVENT4 = 8
} MyEvent_t;

template <class EventT> 
class EventHandler
{
public:
    virtual void on_event(EventT _event) = 0;
};

class MyHandler:public EventHandler<MyEvent_t>{

    virtual void on_event(MyEvent_t _event){

        switch(_event){

            case EVENT1:
                break;

            case EVENT2:
                break;

        }
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    EventHandler<MyEvent_t> *my_handler = new MyHandler();
    MyCallBack rcb(my_handler,&MyHandler<MyEvent_t>::on_event);

    // to check the callback
    rcb();

    return 0;
}

非常感谢任何潜在客户!!!

2 个答案:

答案 0 :(得分:0)

该行

MyCallBack rcb(my_handler,&MyHandler<MyEvent_t>::on_event);

是一个问题,因为on_event接受了一个参数。 <{1}}的构造函数中期望的成员函数指针不带任何参数。

从编译/构建的角度来看,以下内容适用于我。您必须弄清楚如何使其适用于语义观点。

MyCallBack()

答案 1 :(得分:0)

我认为你想要实现的是行动模式。 看看这里:https://en.wikipedia.org/wiki/Command_pattern

现在执行:

#include <iostream>
#include <memory>

struct Action {
    virtual void execute() = 0;
};

struct SomeAction : public Action {
    void execute() {
        std::cout << "SomeAction" << std::endl;
    }
};

struct SomeOtherAction : public Action {
    void execute() {
        std::cout << "SomeOtherAction" << std::endl;
    }
};

class EventHandler {

    std::unique_ptr<Action> action; // The unique ptr will delete action if the event handler is destroyed

public:
    EventHandler() :
        action(new SomeAction())
    {

    }
    void setAction(Action* newAction) {
        action = std::unique_ptr<Action>(newAction);
    }
    void eventCalled() {
        // This function is invoked from the outside if the event happens
        action->execute();
    }
};

int main() {
    EventHandler eventHandler;

    //Some event is called
    eventHandler.eventCalled(); // Output "SomeAction"


    // We change the action later in time
    eventHandler.setAction(new SomeOtherAction());
    // Another Event gets called
    eventHandler.eventCalled(); // Output "SomeOtherAction"
    return 0;
}