好吧,C++里没有匿名函数,看由Pas生成的HPP文件,你会发现它要你实现一个Interface,好在C++的类型声明是随时随地可以进行的,所以对应的实现步骤如下:
1、声明一个类,继承自TCppInterfacedObject<匿名函数类型>以实现匿名函数对应的接口,你愿意写成interface也无所谓,在C++中,struct和class实际上并没啥本质的区别,而interface只是struct的一个别名而已。
class TMyHandler:public TCppInterfacedObject<TMyAnEvent> { public: void __fastcall Invoke(...你的匿名函数参数) { 你的匿名函数实现代码 } }
在这里不要指望象Delphi的匿名函数一样直接访问局部变量,C++的类受C++限制。
2、在需要匿名函数的地方,new 一个你的类的实例,这个实例不需要你去释放,它是一个智能指针,然后就OK了。
示例如下:
void __fastcall TForm1::Button1Click(TObject *Sender){ class TMyEvent:public TCppInterfacedObject<TQXMLObjectPropFilterEvent> { public: void __fastcall Invoke(TQXMLNode* ASender, System::TObject* AObject, System::UnicodeString APropName, bool &Accept) { if (APropName=="Enabled") Accept=False; else Accept=True; } }; TQXMLNode *AXML=new TQXMLNode; AXML->Add("Button1",Button1,False,new TMyEvent); ShowMessage(AXML->Encode(True,L" "); delete AXML; }
是不是感觉上面的代码看着有点乱,好吧,万能的宏出马了:
#define DELPHI_ANON(AType,ATypeName,Code) \ class ATypeName:public TCppInterfacedObject<AType>\ {\ public:\ void __fastcall Invoke##Code\ };
上面的代码也就变成了:
void __fastcall TForm1::Button1Click(TObject *Sender) { DELPHI_ANON(TQXMLObjectPropFilterEvent,TMyEvent, (TQXMLNode* ASender, System::TObject* AObject, System::UnicodeString APropName, bool &Accept) { if (APropName=="Enabled") Accept=False; else Accept=True; } ); TQXMLNode *AXML=new TQXMLNode; AXML->Add("Button1",Button1,False,new TMyEvent); ShowMessage(AXML->Encode(True,L" "); delete AXML; }
实际上,一般情况下TMyEvent这个类型也不是我们关心的,我们更关心的是一个变量名,也就引申出下一个版本:
#define DELPHI_ANON(AType,Code,AVar) \ class AType##AVar:public TCppInterfacedObject<AType>\ {\ public:\ void __fastcall Invoke##Code\ } *AVar=new AType##AVar
那么上面的代码就会变为:
void __fastcall TForm1::Button1Click(TObject *Sender) { DELPHI_ANON(TQXMLObjectPropFilterEvent,TMyEvent, (TQXMLNode* ASender, System::TObject* AObject, System::UnicodeString APropName, bool &Accept) { if (APropName=="Enabled") Accept=False; else Accept=True; },ACallback ); TQXMLNode *AXML=new TQXMLNode; AXML->Add("Button1",Button1,False,ACallback); ShowMessage(AXML->Encode(True,L" "); delete AXML; }
QString新版已经内置了后一种形式的声明,当然如果有更好的办法,我会毫不犹豫的替换掉,不过目前我暂时没有。如果你有更好的实现办法,欢迎提供建议。我觉得通过STL也许有一定的希望,但我没想出来。也许你知道,不要吝啬你的智慧,告诉我吧。