__closure超难问题

swnuwangyun 2005-05-20 10:19:43
//下面的代码用来模拟c#中的事件处理机制
class TEventArgs:TObject
{
};
typedef void __fastcall (__closure *MethodType)(TObject* sender,TEventArgs* args);
class __event
{
private:
list<MethodType> l;
public:
void operator +=(MethodType method)
{
l.push_back(method);
}
void AddHandler(MethodType method)
{
l.push_back(method);
}
};
奇怪的问题是,我在TForm1中定义了一个函数hello,函数声明和MethodType完全一样,然后使用下面的语句:
__event e;
e.AddHandler(this->hello3);
e+=this->hello3;
编译的时候报告e+=this->hello3;有问题,而之前的语句确没有问题,报错:member function must be called or its address taken。这两个函数调用本质是没有区别的,就是函数名称不一样,为什么会出现这种情况呢?
还有,如果把MethodType作为类构造函数的参数进行传送的话,在定义对象的时候也是报告这个错误,不知为何?
...全文
123 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
南郁 2005-05-22
  • 打赏
  • 举报
回复
e+=&this->hello;即可。这是C++的知识。
柯本 2005-05-22
  • 打赏
  • 举报
回复
的确__closure会把类对像本身(this,即指向类的指针,32bit)也压栈
另外,e.AddHandler(this->hello3);是BCB编译器特有的,当类的函数作为参数时,它自动会转__closurer指针,(VC/GCC不支持),但当它在表达式中,即使操作符重载,它也不会自动转成地址,要显式给出取地址符&(VC/GCC也不支持,但支持this->hello,BCB反不支持)
swnuwangyun 2005-05-20
  • 打赏
  • 举报
回复
keiy太厉害了,现在全部通过,工作正常!但是我还是不太明白,__closure这种函数指针到底是什么类型的?我的估计是它是一个64位的整数,前32位为对象指针,后32位为函数指针,不知是否正确?
this->hello和&this->hello有什么区别呢?为什么e.AddHandler(this->hello3);就工作正常了呢?
柯本 2005-05-20
  • 打赏
  • 举报
回复
e+=&this->hello;就可以,至少编译通过,你试试
swnuwangyun 2005-05-20
  • 打赏
  • 举报
回复
下面是我写的模拟C#事件处理代码
//---------------------------------------------------------------------------

#ifndef eventH
#define eventH
//---------------------------------------------------------------------------
#include <vcl.h>
#include <list>
using namespace std;
class TEventArgs:TObject
{
};
template<class S=TObject*,class A=TEventArgs*>
class __delegate
{
typedef void __fastcall (__closure *MethodType)(S sender,A args);
private:
MethodType method;
protected:
__fastcall MethodType readMethod()
{
return method;
}
void __fastcall writeMethod(MethodType method)
{
this->method=method;
}
public:
__property MethodType Method={read=readMethod,write=writeMethod};
public:
__fastcall __delegate()
{
this->method=NULL;
}
__fastcall __delegate(MethodType method)
{
this->method=method;
}
bool __fastcall operator == (__delegate<S,A> delegate)
{
if(this->Method==delegate.Method)
return true;
else
return false;
}
bool __fastcall operator != (__delegate<S,A> delegate)
{
if(this->Method!=delegate.Method)
return true;
else
return false;
}
void __fastcall operator()(S sender,A args)
{
this->method(sender,args);
}
};

template<class S=TObject*,class A=TEventArgs*,class Delegate=__delegate<S,A> >
class __event
{
private:
list<Delegate*> l;
public:
void __fastcall operator += (Delegate* delegate)
{
bool flag=false;
for(list<Delegate*>::iterator i=l.begin();i!=l.end();i++)
{
Delegate* d=*i;
if(*delegate==*d)
{
flag=true;
break;
}
}
if(flag==false)
l.push_back(delegate);
}
void __fastcall operator -= (Delegate* delegate)
{
l.remove(delegate);
}
void __fastcall operator()(S sender,A args)
{
for(list<Delegate*>::iterator i=l.begin();i!=l.end();i++)
{
Delegate* delegate=*i;
(*delegate)(sender,args);
}
}
};
typedef __delegate<> EventHandler;
#endif
下面是测试代码:
void __fastcall TForm1::hello3(TObject* sender,TEventArgs* args)
{
ShowMessage("hello3");
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
EventHandler* handler;
handler=new EventHandler();
handler->Method=this->hello3;
__event<TObject*,TEventArgs*> event;
event+=handler;
//激发事件
event((TObject*)this,new TEventArgs());
event-=handler;
delete handler;
}

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧