文/刘涛
三、析构和终结
当你书写一个可以被其他语言使用的垃圾收集对象时,将发生什么?你针对这个对象是否已经写了一个析构函数?当你正在使用C++,你可以在堆上创建对象,当超出作用域范围后,对象的析构函数将自动运行。当C#或VB应用(不能在堆上创建垃圾收集对象)使用这个对象时将发生什么?这种情况被以一种精巧的方法实时处理。它将对象的析构函数转换为Dispose()方法来使用,所以,拥有析构函数的C++/CLI对象都可以任意使用。
如果你用C#或VB写了一个带有Dispose()方法的类,你可能已经写了一个终结函数,对于终结函数C++/CLI也有一种非常简单的语法。就象foo对象的析构函数叫做~Foo()一样,foo对象的终结函数叫做!Foo(),这两种方法都提醒你他们与构造函数相反。
当一个对象在托管堆上创建后,终结函数开始运行但从不被处理(因为执行的Dispose的级别要高于终结函数)。从某种意义上说,它是一个防护网,使你确信对象能释放其占用的非托管资源。即使使用对象的开发人员忘记了处理它。
四、指针与句柄
对于扩展的托管C++来说,一个主要的限制是C++语言没有变化,两种不同的事情使用相同的符号。"*"的意思要根据代码的上下文而定,试着看看下行代码:
Foo对象在那里创建?内存是否会被自动清除?是否可以象下面代码那样对于指针使用如下算法:
答案依赖于foo是否使用__gc关键词声明,如果它是一个垃圾收集对象,它只能在托管堆上创建,而不能在本地堆、不能在栈上创建。另一方面,如果没有使用__gc关键词声明,这行代码将在本地堆上给对象分配内存,这时候你必须记住使用"delete"来释放它。
一旦编译器的作者拥有了修改语言的自由,正如C++/CLI已经发生的那样,你大可不必担心类对象来自那里,它在哪里存在。你完全可以通过不同的语法来告之对象它应该存在在哪里。
这叫做一个句柄,起初绝大多数C++开发组将^这个符号称为"脱字符号或帽子",现在都叫做帽子。就象指针那样,你从处理*或->符号中解脱出来。这种变化带来的冲击绝大部分是在你的头脑里,你只要看实例的声明就能判断对象生命期的管理,而不用返回查看类的声明。
说到类的声明,__gc and __nogc已经不再存在,在它们的位置上是一些比较"Cool"的、带有空格的关键词,带空格的关键词虽然看上去是两个词,但实际上是含有空格的一个词。
[上一页] [1] [2] [3] [4] [下一页]