Implement event (delegate) (resume) in C ++)

Source: Internet
Author: User

In fact, we need to change it to the true C # version. We mainly need to do two things. First, put CEventHandler on the outside to allow external structures to be directly constructed. Second, implement operator ++ = and operator-=, the following is my implementation code: # pragma once # include <functional> # include <algorithm> # include <vector> # include <assert. h> namespace Common {typedef void * cookie_type; template <typename TR, typename T1, typename T2> class CEventHandler {public: typedef TR return_type; typedef T1 first_type; typedef T2 second_type; typedef std: function <Return_type (first_type, second_type)> handler_type; CEventHandler (const CEventHandler & h) {_ handler = h. _ handler; assert (_ handler! = Nullptr);} CEventHandler (handler_type h) {_ handler = h; assert (_ handler! = Nullptr);} template <typename class_type, typename class_fun> classes (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 () (first_type p1, second_type p2) {return_type ret = return_type (); assert (_ handler! = Nullptr); if (_ handler! = Nullptr) ret = _ handler (p1, p2); return ret;} handler_type _ handler;}; template <typename EventHandler> class CEvent {public: typedef EventHandler event_handler_type; typedef typename usage: return_type; typedef typename event_handler_type: first_type; typedef typename usage: second_type; typedef typename usage: handler_t Ype handler_type ;~ CEvent () {Clear ();} return_type operator () (first_type p1, second_type p2) {return_type ret = return_type (); size_t size = _ handlers. size (); for (auto p: _ handlers) {ret = p-> operator () (p1, p2);} return ret;} cookie_type AddHandler (const event_handler_type & h) {event_handler_type * p = new (nothrow) event_handler_type (h); if (p! = Nullptr) _ handlers. push_back (p); return (cookie_type) p;} void RemoveHandler (cookie_type cookie) {event_handler_type * p = (event_handler_type *) cookie; auto itr = std: find (_ handlers. begin (), _ handlers. end (), p); if (itr! = _ Handlers. end () {_ handlers. erase (itr); delete p;} else {assert (false) ;}} cookie_type operator ++ = (const event_handler_type & pHandler) {return AddHandler (pHandler );} void operator-= (cookie_type cookie) {RemoveHandler (cookie);} void Clear () {if (! _ Handlers. empty () {int n = _ handlers. size (); std: for_each (_ handlers. begin (), _ handlers. end (), [] (event_handler_type * p) {assert (p! = Nullptr); delete p;}); _ handlers. clear () ;}} private: std: vector <event_handler_type *> _ handlers ;};}// Common then we can use: // EventTest. cpp: Defines the entry point for the console application. // # include "stdafx. h "# include <iostream> # include" event2.h "using namespace std; class CObjectX {}; class CClickEventArgs: public CObjectX {}; class CButton: public CObjectX {public: void FireClick () {CClickEventArgs args; OnClicked (this, args);} typedef Common: CEventHandler <int, CObjectX *, CClickEventArgs &> identifier; Common: CEvent <ButtonClickEventHandler> OnClicked ;}; class CMyClass {public: int OnBtuttonClicked (CObjectX * pButton, CClickEventArgs & args) {cout <"CMyClass: Receive button clicked event" <endl; return 1 ;}}; int OnBtuttonClicked_C_fun (CObjectX * pButton, C ClickEventArgs & 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 []) {CButton btn; CMyClass obj; Common: cookie_type c1 = btn. onClicked + = CButton: ButtonClickEventHandler (& obj, & CMyClass: OnBtuttonClicked); Common: cookie_type c2 = btn. onClicked + = CButton: ButtonClickEventHandler (OnBtuttonClicked_C_fun); CMyFunObj functor; Common: cookie_type c3 = btn. onClicked + = CButton: ButtonClickEventHandler (functor); btn. fireClick (); btn. onClicked-= c2; std: cout <endl; btn. fireClick (); system ("pause"); return 0;} is it like C! Finally, let's compare two implementation methods: the first method encapsulates the delegate function type, which is transparent to the outside and easier to use. The second method exposes the types of delegate functions. This method is suitable for scenarios where different types of event processing functions are different and the types of event processing functions are emphasized.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.