将类模板用作C 中的回调

Use class template as callback in C++

本文关键字:回调      更新时间:2023-10-16

我能够在没有类模板的情况下使回调起作用。但是我的要求是通过以模板形式传递的类对象实现回调。我已经在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;
}

感谢很多潜在客户!

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

是一个问题,因为on_event进行了参数。MyCallBack()构造函数中预期的成员函数指针不采用任何参数。

从编译/构建的角度来看,以下对我有效。您必须弄清楚如何使其用于语义的角度。

#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:
      void event() { on_event(EventT()); }
      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;
         default:
            break;
      }
   }
};
int main(int argc, char* argv[])
{
   EventHandler<MyEvent_t> *my_handler = new MyHandler();
   MyCallBack rcb(my_handler,&EventHandler<MyEvent_t>::event);
   // to check the callback
   rcb();
   return 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;
}