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)

Comma-separated string to tabular format

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