SmartOS/Core/Delegate.h

99 lines
3.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef _Delegate_H_
#define _Delegate_H_
// 没有参数和返回值的委托
typedef void (*Func)(void);
// 一个参数没有返回值的委托一般param参数用作目标对象调用者用静态函数包装成员函数
typedef void (*Action)(void* param);
typedef void(*Action2)(void*, void*);
typedef void(*Action3)(void*, void*, void*);
// 事件处理委托一般sender表示事件发出者param用作目标对象调用者用静态函数包装成员函数
typedef void (*EventHandler)(void* sender, void* param);
// 传入数据缓冲区地址和长度,如有反馈,仍使用该缓冲区,返回数据长度
typedef uint (*DataHandler)(void* sender, byte* buf, uint size, void* param);
// 事件处理器
class Delegate
{
public:
void* Method; // 函数指针
void* Target; // 参数
Delegate();
Delegate(void* func);
Delegate(void* func, void* target);
Delegate(Func func);
Delegate(Action func);
Delegate(Action2 func);
Delegate(Action3 func);
template<typename T>
Delegate(void(T::*func)(), T* target) { Method = (void*)&func; Target = target; }
template<typename T, typename TArg>
Delegate(void(T::*func)(TArg), T* target) { Method = (void*)&func; Target = target; }
template<typename T, typename TArg, typename TArg2>
Delegate(void(T::*func)(TArg, TArg2), T* target) { Method = (void*)&func; Target = target; }
void operator()();
void operator()(void* arg);
void operator()(void* arg, void* arg2);
template<typename T>
void operator()()
{
if(Method)
{
auto obj = (T*)Target;
typedef void(T::*TAction)();
auto act = *(TAction*)Method;
(obj->*act)();
}
}
template<typename T, typename TArg>
void operator()(TArg arg)
{
if(Method)
{
auto obj = (T*)Target;
typedef void(T::*TAction)(TArg);
auto act = *(TAction*)Method;
(obj->*act)(arg);
}
}
template<typename T, typename TArg, typename TArg2>
void operator()(TArg arg, TArg arg2)
{
if(Method)
{
auto obj = (T*)Target;
typedef void(T::*TAction)(TArg, TArg2);
auto act = *(TAction*)Method;
(obj->*act)(arg, arg2);
}
}
};
/*
成员函数指针的操作
class A{
public:
void Func(int){...}
};
要取得Func函数指针void (A::*pFunc)(int)=&A::Func;
::*是一个特殊操作符表示pFunc是一个指针指向A的成员。获取成员函数的地址不能通过类对象来获取必须通过类名获取而且要加上取地址操作。
那么如果通过指针来调用该函数成员函数都隐含了一个this参数表示函数要操作的对象我们只获取了函数的指针还缺少一个对象作为this参数
为了这个目的,我们先创建一个对象,然后通过该对象来调用成员函数指针:
A a; ( a.*pFunc)(10);
A* pa=&a;
(pa->*pFunc)(11);
第一种方式通过对象本身调用,第二种方式通过对象指针调用,效果一样。
使用类模板:
要调用一个成员函数,仅仅有成员函数指针是不够的,还需要一个对象指针,所以要用一个类将两者绑到一起。
*/
#endif //_Delegate_H_