Simple effective Event/Delegate Method in c++
C++ delegate/event
Callback class (base class):
if return Type is void
now if return type is not void then class will be defined as
Member function (method) callback (Derived Class):
Member function (method) callbacks keep track of which object address to use for the
when return type is void
Delegate class:
Now this the final class which will be used to access from our main code.
if return type is void
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:
Took Help from following link
//http://allenchou.net/2012/04/easy-c-delegates/
Callback class (base class):
if return Type is void
template <typename Param0>the
class Callback
{
public:
virtual void invoke(Param0 param0) = 0;
};
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>The
class Callback
{
public:
virtual Ret invoke(Param0 param0) = 0;
};
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>or if return type is not void
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);
}
};
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>or if return type is not void
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);
}
};
template <typename Ret, typename Param0>That's it. all done.
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);
}
};
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)MyClass_2:
{
if (this->PropertyChangedEvent != nullptr)
(*this->PropertyChangedEvent)(&val); //this will call registered function
}
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
Post a Comment