简体   繁体   中英

callback function design C++

I'm trying to implement a callback manager that can register and execute the callbacks from different classes, which each classes are from a different DLL.

Each of these classes derives from a common base class. I know how a single class can make use of a template class like below to register and call its own function, but how can this be applied to use on multiple classes sharing the same callback manager?

Any help will be greatly appreciated.

file: callbacktemplate.h
------------------------
#include <functional>
#include <string>
template <class cInstance>
class cCallBackManager
{
private:
    typedef void (cInstance::*tFunction)();
    typedef std::map<std::string, tFunction> funcMap;
     funcMap i_funcMap;
public:
    void SetFunPointer(std::string funcName, tFunction function)
    {
        i_funcMap.insert(std::pair<std::string, tFunction>(funcName, function));            
    }

    void GetFunPointer(cInstance& obj) //how to call this without knowing the type?
    {
        for (funcMap::iterator it = i_funcMap.begin();it!=i_funcMap.end(); ++it)
        {
            (obj.*(it->second))(); 
        }
    }
};


file:example.h
---------------
#include "callbacktemplate.h"
class A: public base
{
private:
    cCallBackManager<A> callback;
public:
     A()
     {
         callback.SetFunPointer<A>("eventA", &A::testcallback);
         callback.GetFunPointer(&this);   //how to generalize this so this can be called from the callback manager with the class object?
     };
     ~A(){};
     void testCallback();
};

class B: public base
{
private:
    cCallBackManager<B> callback;
public:
     B()
     {
         callback.SetFunPointer<B>("eventB", &B::testcallback);
     };
     ~B(){};
     void testCallback();
};

file: main.cpp
------------------
#include "derived.h"

int main()
{
 A a;
 B b;
 //create a callback manager to execute the callback?
 callbackmgr.execute() //execute all the callback

 return 0;
}

lf not using templatized callback manager, how can i achieve something like SetFunPointer(EVENT_NAME, (Base Class)A::testCallback)?

Thanks guys. I've managed to come up with something with your "pointers". :)

File: cCallBackInterface.h

template<class cClass>
class cCallBackInterface
{
public:
cCallBackInterface(){};
~cCallBackInterface(){};

typedef void (cClass::*Function)();

cCallBackInterface(cClass* obj, Function _Function)
{
    cInstance = obj;
    m_Function = _Function;
}

void execute()
{
     (cInstance->*m_Function)();
}

private:
cClass* cInstance;
Function m_Function;
};

File: base.h

class BaseModel;
typedef cCallBackInterface<BaseModel> CallBackInterface;
typedef void(BaseModel::*basefn)();

class BaseModel 
{
public:
BaseModel(){};
~BaseModel(){};

}
};


class derived : public BaseModel
{
public:
derived(){};
~derived(){};

void dosomething()
{
    cout << "derived class is doing something." << endl;
}


};

File: main.cpp

int main()
{  
derived a;

std::vector<CallBackInterface> callback;

callback.push_back(CallBackInterface(&a, (basefn)(&derived::Adosomething)));

for(int i = 0; i < callback.size(); i++)
    callback[i].execute();

return 0;
}

You can look at this question regarding using member-function pointers .

What it boils down to is that you need the instance as well as the mem-func pointer, you cannot have a generic one to be used anywhere.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM