Simple effective Event/Delegate Method in c++

C++ delegate/event

Callback class (base class):
if return Type is void
template <typename Param0>
class Callback
{
public:
    virtual void invoke(Param0 param0) = 0;
};
the Param0 type is the type of the one parameter passed to the function. You can use more than one parameter to pass by using  
template <typename Param0, typename Param1
then invoke method will be replaced by 
virtual void invoke(Param0 param0, Param1 param1) = 0;
 
now if return type is not void then class will be defined as
template <typename Ret, typename Param0>
class Callback
{
public:
    virtual Ret invoke(Param0 param0) = 0;
};
The Ret is the return type of the function.

Member function (method) callback (Derived Class):
Member function (method) callbacks keep track of which object address to use for the this pointer while invoking the method.

when return type is void
template <typename Param0, typename Object, typename Method>
class MethodCallback : public Callback<Param0>
{
private:
    void *object_;
    Method method_;

public:
    MethodCallback(void *object, Method method)
        : object_(object)
        , method_(method)
    {}

    virtual void invoke(Param0 param0)
    {
        Object *obj = static_cast<Object *>(object_);
        (obj->*method_)(param0);
    }
};
   or if return type is not void
template <typename Ret, typename Param0, typename Object, typename Method>
class MethodCallback : public Callback<Ret, Param0>
{
private:
    void *object_;
    Method method_;

public:
    MethodCallback(void *object, Method method)
        : object_(object)
        , method_(method)
    {}

    virtual Ret invoke(Param0 param0)
    {
       
Object *obj = static_cast<Object *>(object_);
        return (obj->*method_)(param0);
    }
};

Delegate class:
Now this the final class which will be used to access from our main code.
if return type is void
template <typename Param0>
class Delegate
{
private:
    Callback<Param0> *callback_;

public:

    template <typename Object, typename Method>
    Delegate(Object *object, Method method) : callback_(new MethodCallback<Param0, Object, Method>(object, method))
    {}

    ~Delegate(void) { delete callback_; }

    void operator()(Param0 param0)
    {
        callback_->invoke(param0);
    }
};
   or if return type is not void
template <typename Ret, typename Param0>
class Delegate
{
private:
    Callback<Ret, Param0> *callback_;

public:

    template <typename
Object, typename Method>
    Delegate(
Object *object, Method method)
        : callback_(new MethodCallback<Ret, Param0,
Object, Method>(object, method))
    {}

    ~Delegate(void) { delete callback_; }

    Ret operator()(Param0 param0)
    {
        return callback_->invoke(param0);
    }
};
That's it. all done.

Example:
Now going to write a sample example which will make it more understandable about how it works.
Here I used void as return type and also used void* as parameter to pass any type of parameter. Its not mandatory to use pointer. You can use any data type.
MyClass will invoke FuncPropertyChangedEvent (a method of MyClass_2) which will be registered/bound in constructor of MyClass_2 here with a delegate function pointer of MyClass.

MyClass:
typedef Delegate<void*> PropertyChangedHandler;
class MyClass
{
   
private:
    void SendData(int val);
public:
    PropertyChangedHandler* PropertyChangedEvent;

   
MyClass();
    ~
MyClass();
};

void MyClass::SendData(int val)
{
    if (this->PropertyChangedEvent != nullptr)
        (*this->PropertyChangedEvent)(&val);  //this will call registered function
}
MyClass_2:
Class MyClass_2
{
private:
    MyClass obj;
    void FuncPropertyChangedEvent(void*);

public:
    MyClass_2();

MyClass_2::MyClass_2()
{
    obj.PropertyChangedEvent = new PropertyChangedHandler(this, &MyClass_2::FuncPropertyChangedEvent);
}

void MyClass_2::FuncPropertyChangedEvent(void* param0)
{
    int val = *((int*)param0);
//now use this val

}

Took Help from following link
//http://allenchou.net/2012/04/easy-c-delegates/

Comments

Popular posts from this blog

How to Build WPF project with Setup file (Installer Project)

Build shared library of ffmpeg with x264 to use in visual studio win32 project

Comma-separated string to tabular format