我正在尝试找出如何在C++/CLI中正确清理我的对象。
我已经阅读或浏览了这两篇文章(one, two),并查看了标准,还看了一些其他问题,特别是this one。
我有各种信息:
- 最终器应清理非托管资源(因此在对象进行垃圾回收时,所有内容都会被清理)。
- 析构函数应清理托管资源(删除 Foo 还是 Foo.Dispose()?)并调用最终器(参见 1)。
- 析构函数和最终器都可以被多次调用(参见 3 第 8.8.8 页末尾)。
- 如果调用析构函数,则最终器将不再被调用(根据 1)(不是由 CLR 调用,也就是说,您仍然可以自己调用它)。
- 析构函数将调用基类析构函数(参见 3 第 25 页)。
- 具有最终器的类应始终具有析构函数(可能是为了确定性地清理非托管资源)。
- 对最终器的调用不会调用基类的最终器(3 第 131 页的 19.13.2)。
但是,部分原因造成了很多混乱:
- C#中的finalizers被称为destructors
- 析构函数在内部生成Dispose和Finalize方法(不确定Finalize),但Finalize方法不是finalizer
- C++中析构函数的语义不同,同时具有确定性清理和垃圾回收的复杂性。
我想要的答案是一个包含各种数据类型(托管、非托管、可处理的托管等)的类,并且拥有正确编写的析构函数和finalizer。
我还有两个更具体的问题:
- 通过在析构函数/终结器上设置
bool hasBeenCleanedUp
成员并将整个代码都放在条件语句中来处理可能被多次调用的情况是否可接受? - 什么样的数据只能由析构函数清除,但不能在finalizer中清除,因为它可能已经被垃圾回收清除了?