轻松使用C++深入研究.NET委托与事件设计(6) | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
http://www.sina.com.cn 2004年06月07日 12:04 天极网 | ||||||||||
文/翻译 曾毅 托管C++ 由于委托和事件是.NET框架的一部分,所有的.NET支持的语言都可以使用它们。我所描述的基于模版的实现是专门针对C++的。Microsoft采用了不同的方法在C++中将这个功能公开—对于标准C++的扩展称为托管C++。也许你并不感到太吃惊,在托管C++中编写这个例子与最初的代码是那么相似:
public __gc struct DelegatesAndEvents { __event void MyPrintString(String* s); void FirePrintString(String* s) { MyPrintString(s); } }; __gc struct MyDelegates { String* Name; void SimpleDelegateFunction(String* s) { Console::WriteLine ("SimpleDelegateFunction called from {0} string={1}",Name, s); } }; void ManagedCpp() { DelegatesAndEvents* dae = new DelegatesAndEvents(); MyDelegates* d = new MyDelegates(); d->Name = "Obj1"; __hook(&DelegatesAndEvents::MyPrintString, dae, &MyDelegates::SimpleDelegateFunction, d); dae->FirePrintString(S"Event fired!"); } 关键字__gc标志着这个类是被垃圾回收机制控制的(托管的);我们不需要调用delete函数。仅仅一个__event关键字就完成了我们上面代码的大部分功能。需要注意的是托管C++使用__hook关键字来替代上面讨论的操作符+=。你会发觉使用-Fx标记[4]调用(托管)C++编译器编译上述代码和检查产生的结果文件.mrg非常有趣。在编译器级加入新功能而不是编写模板显然要容易得多了。 结论 通过使用极为高级的C++技巧,我已经向大家展示了用C++为简单的样例代码实现委托与事件是可行的。这个实现主要考虑基于.NET框架。更为一流和纯粹的C++解决方案可以使用C++标准库中的适配器和联编程序。 参考文献 [1] Jeffrey Richter. “An Introduction to Delegates,” MSDN Magazine, April 2001. < msdn.microsoft.com/msdnmag/issues/01/04/net/default.aspx >. [2] Richard Grimes. “.NET Delegates: Making Asynchronous Method Calls in the .NET Environment,” MSDN Magazine, August 2001. <msdn.microsoft.com/msdnmag/issues/01/08/Async/default.aspx>. [3] Jeffrey Richter. “Delegates, Part 2,” MSDN Magazine, June 2001. < msdn.microsoft.com/msdnmag/issues/01/06/net/default.aspx> [4] Bobby Schmidt. “The Red Pill,” April 23, 2002. <msdn.microsoft.com/library/default.asp?url=/library/en-us/dndeepc/html/deep04232002.asp > 译者注: 译注1:Type-safe:按照2003年微软官方提供的术语表翻译为“类型安全”。 译注2:overload resolution: 按照2003年微软官方提供的术语表翻译为“重载决策”。 译注3:原文中所列参考文献的地址已经失效,译文中提供的是在本文翻译截稿时所示参考的最新有效链接,为尊重原著者特此说明。 译注4:destructor一词按照简体中文常用译法译为“反引用”。 译注5:关于文中采用的reinterpret_cast。事实上,reinterpret_cast在这里是通不过的。因为我们不可能对成员函数指针进行所谓的类型转换。这个例子实际上是在比较对象,转换的也是对象,而不是对象的成员。而这个示例却将reinterpret_cast作为解决的方式,即直接比较的是对象的成员,而不考虑对象。也就是说,试图转换对象的成员。而失去类型转换的真正意图。为什么作者在这里用了reinterpret_cast,意为“重新意义上的强制转换“。这种转换并不是基于类型或者是对象的,更谈不上类型安全了。委托的本质上讲是函数指针,不过,它需要首先进行类型检查。我们说委托对象的存在,只是为了类型检查,真正有意义的还是其方法。所以reinterpret_cast相当于一种解决方式。 【责任编辑:方舟】
|