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.