CSDN博客

img coolcch

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

发表于2004/3/21 17:39:00  549人阅读

前两天看程序员杂志
看到关于 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;
}
0 0

相关博文

我的热门文章

img
取 消
img