用 C++ 实现 C# 中的 委托/事件 (1-delegateEMU.cpp)

来源:互联网 发布:空间数据库 吴信才 编辑:程序博客网 时间:2024/06/04 22:47

 

前两天看程序员杂志
看到关于 C# 中的委托/事件
觉得用起来好像是挺方便的
本人热衷于 C++
想想用 C++ 来模拟似乎也可以
于是就有了下面的代码...
(VC6 不支持偏特化 本人工作环境就是 VC6 痛啊~~~)

没有返回值的函数用 delegate
否则就用 delegate_rt
functor 也一样 functorN/functorN_rt
delegate 的模板参数可以是函数指针(非成员函数)
也可以是 functor
还可以是 delegate
functor 可用 make_functor/make_functor_rt 来生成
要是有偏特化 就可以去掉讨厌的 _rt 了 :(

关于委托 boost里有现成的
不过可能 VC6 里用不了

这些代码旨在个人研究
如果大家发现其中问题 希望能指出

//filename: delegateEMU.cpp#include <stdio.h>#pragma warning(disable:4786)#include "delegate.h"#include "event.h"#include "functor.h"#include <functional>class MyEventArgs : public EventArgs{public:  MyEventArgs(const char* Context = "") : context(Context) {}  const char* context;};typedef delegate<void (*)(object, MyEventArgs&)> EventHandler1;typedef delegate<functor2<object, MyEventArgs&> > EventHandler2;class Provider{  public:  event<EventHandler1> OkClick1;  public:  event<EventHandler2> OkClick2;};static void global_Process_OkClick(object source, MyEventArgs& e){  printf("global_Process_OkClick, \t%s\n", e.context);}class Master_base{public:  public: Provider pro;  public: Master_base()  {    pro.OkClick1 += EventHandler1(static_Process_OkClick);    pro.OkClick2 += EventHandler2(      make_functor(this, &Master_base::Process_OkClick));    pro.OkClick2 += EventHandler2(      make_functor(&Master_base::static_Process_OkClick));    pro.OkClick2 += EventHandler2(      make_functor(global_Process_OkClick));  }  protected: void Process_OkClick(object source, MyEventArgs& e)  {    printf("       Process_OkClick, \t%s\n", e.context);  }  public: static void static_Process_OkClick(object source, MyEventArgs& e)  {    printf("static_Process_OkClick, \t%s\n", e.context);  }  public: virtual void test_virtual() const  {    printf("Master_base::test_virtual const\n");  }  public: void mem_func__()  {    printf("Master_base::mem_func__\n");  }  public: void mem_func__int(int x)  {    printf("Master_base::mem_func__int %d\n", x);  }  public: void mem_func__int_str(int x, const char* str)  {    printf("Master_base::mem_func__int %d %s\n", x, str);  }  public: int mem_func_int_()  {    printf("Master_base::mem_func_int_\n");    return 123;  }  public: int mem_func_int_int(int x)  {    printf("Master_base::mem_func_int_int %d\n", x);    return x;  }  public: int mem_func_int_int_str(int x, const char* str)  {    printf("Master_base::mem_func_int_int %d %s\n", x, str);    return x;  }};class Master_derived: public Master_base{  public: Master_derived()  {    pro.OkClick1 += EventHandler1(static_Process_OkClick_Myself);    pro.OkClick2 += EventHandler2(      make_functor(this, &Master_derived::Process_OkClick_Myself));    pro.OkClick2 -= EventHandler2(      make_functor((Master_base*)this, &Master_base::Process_OkClick));    pro.OkClick2 -= EventHandler2(      make_functor(this, &Master_derived::Process_OkClick_Myself1));    pro.OkClick2 += EventHandler2(      make_functor(&Master_derived::static_Process_OkClick_Myself));    pro.OkClick2 -= EventHandler2(      make_functor(global_Process_OkClick));  }  protected: void Process_OkClick_Myself(object source, MyEventArgs& e)  {    printf("       Process_OkClick_Myself, \t%s\n", e.context);  }  private: void Process_OkClick_Myself1(object source, MyEventArgs& e)  {    printf("       Process_OkClick_Myself1, \t%s\n", e.context);  }  static void static_Process_OkClick_Myself(object source, MyEventArgs& e)  {    printf("static_Process_OkClick_Myself, \t%s\n", e.context);  }  public: virtual void test_virtual() const  {    printf("Master_derived::test_virtual const\n");  }};class MainClass{public:  void Main()  {    Master_base example1;    Master_derived example2;    printf("  example1.pro.OkClick1:\n");    example1.pro.OkClick1(this, MyEventArgs("example1.pro.OkClick1"));    printf("  example2.pro.OkClick1:\n");    example2.pro.OkClick1(this, MyEventArgs("example2.pro.OkClick1"));    printf("\n");    printf("  example1.pro.OkClick2:\n");    example1.pro.OkClick2(this, MyEventArgs("example1.pro.OkClick2"));    printf("  example2.pro.OkClick2:\n");    example2.pro.OkClick2(this, MyEventArgs("example2.pro.OkClick2"));  }};void testfunc__(){  printf("testfunc__\n");}void testfunc__int(int i){  printf("testfunc__int %d\n", i);}void testfunc__int_str(int i, const char* j){  printf("testfunc__int_str %d %s\n", i, j);}int testfunc_int_(){  printf("testfunc_int_\n");  return 111;}int testfunc_int_int(int i){  printf("testfunc_int_int %d\n", i);  return i;}int testfunc_int_int_str(int i, const char* j){  printf("testfunc_int_int_str %d %s\n", i, j);  return i;}typedef void (*func__)();typedef void (*func__int)(int);typedef void (*func__int_str)(int, const char*);typedef int (*func_int_)();typedef int (*func_int_int)(int);typedef int (*func_int_int_str)(int, const char*);int main(){  printf("event:\n");  MainClass().Main();  printf("\n functor:\n");  Master_base mb;  Master_derived md;  printf("\n  func__:\n");  delegate<func__> ffunc__(testfunc__);  ffunc__ = delegate<func__>(testfunc__);  ffunc__ -= delegate<func__>(testfunc__);  ffunc__ += delegate<func__>(testfunc__);  ffunc__ = ffunc__ - delegate<func__>(testfunc__);  ffunc__ = ffunc__ + delegate<func__>(testfunc__);  ffunc__ = delegate<func__>(testfunc__) + ffunc__;  ffunc__ = testfunc__;  ffunc__ -= testfunc__;  ffunc__ += testfunc__;  ffunc__ = ffunc__ - testfunc__;  ffunc__ = ffunc__ + testfunc__;  ffunc__ = testfunc__ + ffunc__;  ffunc__();  printf("  functor.func__:\n");  delegate<functor0> ffunc__1(make_functor(testfunc__));  ffunc__1 += make_functor(&mb, &Master_base::mem_func__);  ffunc__1();  printf("\n  func__int:\n");  delegate<func__int> ffunc__int(testfunc__int);  ffunc__int(888);  printf("  functor.func__int:\n");  delegate<functor1<int> > ffunc__int1(make_functor(testfunc__int));  ffunc__int1 += make_functor(&mb, &Master_base::mem_func__int);  ffunc__int1(777);  printf("\n  func__int_str:\n");  delegate<func__int_str> ffunc__int_str(testfunc__int_str);  ffunc__int_str(888, "ccc");  printf("  functor.func__int_str:\n");  delegate<functor2<int, const char*> >     ffunc__int_str1(make_functor(testfunc__int_str));  ffunc__int_str1 += make_functor(&mb, &Master_base::mem_func__int_str);  ffunc__int_str1(777, "hhh");  printf("\n  func_int_:\n");  delegate_rt<int, func_int_> ffunc_int_(testfunc_int_);  printf("ffunc_int_()=%d\n", ffunc_int_());  printf("  functor.func_int_:\n");  delegate_rt<int, functor0_rt<int> >     ffunc_int_1(make_functor_rt(testfunc_int_));  printf("ffunc_int_1()=%d\n", ffunc_int_1());  ffunc_int_1 -= make_functor_rt(testfunc_int_);  ffunc_int_1 += make_functor_rt(&mb, &Master_base::mem_func_int_);  printf("ffunc_int_1()=%d\n", ffunc_int_1());  printf("\n  func_int_int:\n");  delegate_rt<int, func_int_int> ffunc_int_int(testfunc_int_int);  printf("ffunc_int_int()=%d\n", ffunc_int_int(888));  printf("  functor.func_int_int:\n");  delegate_rt<int, functor1_rt<int, int> >     ffunc_int_int1(make_functor_rt(testfunc_int_int));  printf("ffunc_int_int1()=%d\n", ffunc_int_int1(777));  ffunc_int_int1 -= make_functor_rt(testfunc_int_int);  ffunc_int_int1 += make_functor_rt(&mb, &Master_base::mem_func_int_int);  printf("ffunc_int_int1()=%d\n", ffunc_int_int1(777));  printf("\n  func_int_int_str:\n");  delegate_rt<int, func_int_int_str> ffunc_int_int_str(testfunc_int_int_str);  printf("ffunc_int_int_str()=%d\n", ffunc_int_int_str(888, "ccc"));  printf("  functor.func_int_int_str:\n");  delegate_rt<int, functor2_rt<int, int, const char*> >     ffunc_int_int_str1(make_functor_rt(testfunc_int_int_str));  printf("ffunc_int_int_str1()=%d\n", ffunc_int_int_str1(777, "hhh"));  ffunc_int_int_str1 -= make_functor_rt(testfunc_int_int_str);  ffunc_int_int_str1 += make_functor_rt(&mb, &Master_base::mem_func_int_int_str);  printf("ffunc_int_int_str1()=%d\n", ffunc_int_int_str1(777, "hhh"));  printf("\nstatic function size:\t%d\n",     sizeof(&global_Process_OkClick));  printf("member function size:\t%d\n",     sizeof(&Master_base::mem_func__));  printf("virtual member function size:\t%d\n",     sizeof(&Master_base::test_virtual));  printf("\n");  delegate<functor0> ftest_virtual;  ftest_virtual = delegate<functor0>(ffunc__1)                + delegate<functor0>(make_functor((Master_base*)&md,                                      &Master_base::test_virtual));  ftest_virtual();  printf("  test_virtual2:\n");  ftest_virtual = ftest_virtual                - make_functor(&md, &Master_derived::test_virtual);  ftest_virtual = ftest_virtual                + make_functor(&mb, &Master_base::test_virtual);  ftest_virtual = make_functor(&mb, &Master_base::test_virtual)                 + ftest_virtual;  ftest_virtual();  printf("\n  Test make_functor global:\n");  EventHandler2 teststatic1(make_functor(&global_Process_OkClick));  teststatic1((object)NULL, MyEventArgs());  MyEventArgs e;  functor2<object, MyEventArgs&>     teststatic2(make_functor(&global_Process_OkClick));  teststatic2((object)NULL, e);  make_functor(&global_Process_OkClick)(NULL, e);  printf("\n  Test make_functor static member:\n");  EventHandler2 teststatic3(make_functor(&Master_base::static_Process_OkClick));  teststatic3((object)NULL, MyEventArgs());  functor2<object, MyEventArgs&>     teststatic4(make_functor(&Master_base::static_Process_OkClick));  teststatic4((object)NULL, e);  make_functor(&Master_base::static_Process_OkClick)(NULL, e);  std::vector<int> for_each_test(1, 1);  for_each_test.push_back(2);  for_each_test.push_back(3);  printf("\n  for_each test ffunc__int:\n");  std::for_each(for_each_test.begin(), for_each_test.end(), ffunc__int);  printf("\n  for_each test ffunc__int1:\n");  std::for_each(for_each_test.begin(), for_each_test.end(), ffunc__int1);  printf("\n  for_each test ffunc_int_int:\n");  std::for_each(for_each_test.begin(), for_each_test.end(), ffunc_int_int);  printf("\n  for_each test ffunc_int_int1:\n");  std::for_each(for_each_test.begin(), for_each_test.end(), ffunc_int_int1);  delegate<delegate<functor1<int> > > delegate_for_delegate_test(ffunc__int1);  delegate_for_delegate_test += ffunc__int1;  printf("\n  delegate_for_delegate_test 1:\n");  std::for_each(for_each_test.begin(), for_each_test.end(),     delegate_for_delegate_test);  ffunc__int1 -= make_functor(testfunc__int);  delegate_for_delegate_test += ffunc__int1;  printf("\n  delegate_for_delegate_test 2:\n");  std::for_each(for_each_test.begin(), for_each_test.end(),     delegate_for_delegate_test);  return 0;}