-- 作者:admin
-- 发布时间:11/9/2004 2:26:00 AM
-- 修订版Managed C++中析构函数的语义更改
发信人: flier (小海 [寻找风车中]), 信区: DotNET 标 题: 修订版Managed C++中析构函数的语义更改 发信站: BBS 水木清华站 (Mon Mar 29 23:38:55 2004), 转信 http://61.155.107.20/user8/flier_lu/main.asp?id=1485755 修订版Managed C++中析构函数的语义更改 上周Lippman在其Blog上发表了一篇介绍新版本Managed C++中析构函数语义变化的文章:Changes in Destructor Semantics in Support of Deterministic Finalization。 我们知道在C#和Managed C++中,析构函数实际上被编译器翻译成对Object.Finalize函数的重载。例如在Managed C++中定义如下的类 以下为引用: __gc class A { public: ~A() { Console::WriteLine(S"in ~A"); } }; __gc class B : public A { public: ~B() { Console::WriteLine(S"in ~B"); } }; 在Managed C++的实现上被编译器自动转换成 以下为引用: // internal transformation of destructor under V1 __gc class A { public: void Finalize() { Console::WriteLine(S"in ~A"); } }; __gc class B : public A { public: void Finalize() { Console::WriteLine(S"in ~B"); A::Finalize(); } }; 但为了语义上兼容C++的程序,Managed C++同时也提供了一个虚方法实现析构函数。 以下为引用: __gc class A { public: virtual ~A() { System::GC::SuppressFinalize(this); A::Finalize(); } }; __gc class B : public A { public: virtual ~B() { System::GC:SuppressFinalize(this); B::Finalize(); } }; 这样一来就允许Managed C++用户显式地调用类的Finalize()函数。 虽然这样的思路在目前CLR版本中可以正常运转,但实际上和Dispose模式存在重合和冲突的地方,而且频繁使用Finalizer也会导致效率的降低。因此在新版本的Managed C++中,析构函数改为使用Dispose模式来实现。上面的代码被编译器自动转换为 以下为引用: // internal transformation of destructor under V2 __gc class A : IDisposable { public: void Dispose() { System::GC::SuppressFinalize(this); Console::WriteLine( "in ~A"); } } }; __gc class B : public A { public: void Dispose() { System::GC::SuppressFinalize(this); Console::WriteLine( "in ~B"); A::Dispose(); } }; 而对此类进行的析构操作,无论是直接调用类的析构函数,还是通过delete关键字隐式调用,都会被编译器翻译成对Dispose方法的调用。 但这样一来GC就无法访问类的析构代码了,因为析构函数没有直接被转换成Finalize函数。为此Managed C++新版本提供了一个修订语法,通过'!'前缀支持显式定义Finalize函数,例如: 以下为引用: public ref class R { public: !R() { Console::WriteLine( "I am the R::finalizer()!" ); } }; 被新版本Managed C++编译器自动转换为 以下为引用: // internal transformation under V2 public ref class R { public: void Finalize() { Console::WriteLine( "I am the R::finalizer()!" ); } }; 为了支持从老版本的Managed C++中将代码移植出来,MS还准备开发一个自动转换工具,将原本显式定义的Dispose()方法转换为析构函数;将原本定义的析构函数转换为!前缀支持的显式Finalize函数定义。 有趣的是,这一实现思路与Delphi.NET完成类似析构函数语义的思路很相似,有兴趣进一步了解的朋友可以参考这篇文章 Object Destructors and Finalizers in .NET Using C# and Delphi for .NET 几位Borland系统的老兄也针对相关问题有一些不错的评论: Allen Bauer 的 The rules have not changed Nick Hodges 的 On Finalizers at Filafel -- . 生命的意义在于 /\ ____\ /\_ \ /\_\ http://flier.yeah.net. . 希望 \ \ \___/_\/\ \ \/_/__ __ _ _★ . . 工作 \ \ ____\\ \ \ /\ \ /'__`\ /\`'_\ . . 爱你的人 \ \ \___/ \ \ \___\ \ \/\ __// \ \ \/ . . 和你爱的人 \ \___\ \ \_____\ \__\ \____\ \ \_\ . . …… \/___/ \/_____/\/__/\/____/ \/_/ @nsfocus.com. ※ 来源:·BBS 水木清华站 smth.org·[FROM: 211.167.254.*] 上一篇 返回上一页 回到目录 回到页首 下一篇
|