在C++中实现事件(委托)(二)
cked;
};
class CMyClass
{
public:
int OnBtuttonClicked(CObjectX* pButton, CClickEventArgs& args)
{
cout << "CMyClass: Receive button clicked event" << endl;
return 1;
}
};
int OnBtuttonClicked_C_fun(CObjectX* pButton, CClickEventArgs& args)
{
cout << "C Style Function: Receive button clicked event" << endl;
return 1;
}
class CMyFunObj
{
public:
int operator()(CObjectX* pButton, CClickEventArgs& args)
{
cout << "Functor: Receive button clicked event" << endl;
return 1;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std::placeholders;
CButton btn;
CMyClass obj;
Common::cookie_type c1 = btn.OnClicked.AddHandler(&obj, &CMyClass::OnBtuttonClicked);
Common::cookie_type c2 = btn.OnClicked.AddHandler(OnBtuttonClicked_C_fun);
CMyFunObj functor;
Common::cookie_type c3 = btn.OnClicked.AddHandler(functor);
btn.FireClick();
btn.OnClicked.RemoveHandler(c2);
std::cout << endl;
btn.FireClick();
system("pause");
return 0;
}
以下是测试结果:
可以看到, 我们在普通C函数, 类成员函数和仿函数(functor)中都测试通过。
另外对于事件函数返回值为void的情况,会编译出错,我们需要偏特化一下:
template< typename T1, typename T2>
class CEvent
{
public:
typedef void return_type;
typedef T1 first_type;
typedef T2 second_type;
typedef std::function handler_type;
~CEvent()
{
Clear();
}
return_type operator()(first_type p1, second_type p2)
{
size_t size = _handlers.size();
for(size_t i=0; i
{
_handlers[i]->operator()(p1, p2);
}
}
cookie_type AddHandler(std::function h)
{
CEventHandler*p = new(nothrow) CEventHandler(h);
if(p != nullptr) _handlers.push_back(p);
return (cookie_type)p;
}
template
cookie_type AddHandler(class_type* pThis, class_fun f)
{
CEventHandler* p = new(nothrow) CEventHandler(pThis, f);
if(p != nullptr) _handlers.push_back(p);
return (cookie_type)p;
}
void RemoveHandler(cookie_type cookie)
{
CEventHandler* p = (CEventHandler*)cookie;
auto itr = std::find(_handlers.begin(), _handlers.end(), p);
if(itr != _handlers.end())
{
_handlers.erase(itr);
delete p;
}
else
{
assert(false);
}
}
void Clear()
{
if(!_handlers.empty())
{
int n = _handlers.size();
std::for_each(_handlers.begin(), _handlers.end(), [](CEventHandler* p)
{
assert(p != nullptr);
delete p;
});
_handlers.clear();
}
}
private:
class CEventHandler
{
public:
CEventHandler(handler_type h)
{
_handler = h;
assert(_handler != nullptr);
}
template
CEventHandler(class_type* pThis, class_fun object_function)
{
using namespace std::placeholders;
_handler = std::bind(object_function, pThis, _1, _2);
assert(_handler != nullptr);
}
return_type operator(