Sar*_*ien 7 destructor c++-cli finalizer
我试图弄清楚如何在C++/CLI中正确清理我的对象之后.
我已经阅读或浏览了这两篇文章(一,二)并查看了标准并查看了其他一些问题,特别是这一个问题.
我有各种各样的信息:
但也有很多混乱,部分是由于这一事实造成的
我想要的答案是一个类的例子,它包含它可能包含的所有不同类型的数据(托管,非托管,托管但是一次性的,你能想到的其他任何东西)和正确编写的析构函数和终结器.
我有两个更具体的问题:
bool hasBeenCleanedUp成员处理多次被调用的可能性并使析构函数/终结器中的整个代码以此为条件,是否可以接受?对您的问题不是一个完整的答案,但是太长,无法发表评论.
在完全托管的世界中,每个对象只引用托管对象,不需要终结器或析构函数,因为唯一的资源是内存,GC负责处理它.
当您引用非托管资源时,您有责任在不再需要它们时释放它们.
因此,您需要实现专用的清理代码.
有两种可能性:
你知道什么时候你不再需要非托管资源,所以你可以确定地运行你的清理代码,这是通过析构函数/ Dispose实现的
您不知道何时不再需要这些资源,因此您在最后可能的时刻推迟清理,当GC收集包装资源的对象时,这是通过终结器实现的
您认为在第一种情况下更好,因为您不会消耗超过您需要的内存,并且可以避免GC进程的额外开销.
您通常实现这两种方法,因为实例的生命周期可能因使用情况而异.
在CLR级别,没有确定性清理,只有终结器.
在语言/ API级别,支持确定性清理:
在本机C++中,您在退出作用域或"删除"时调用了析构函数
在.Net世界中,你有Dispose模式
在纯托管C++/CLI中,世界析构函数映射到Dispose
当您有机会确切知道何时可以运行清理代码时,您可以调用(或让基础结构调用)析构函数.清理完成后,您可以清除所有完成过程,以便在下一个GC时立即收集对象.
关于你的第一个要点的一些澄清:
是
析构函数也负责清理非托管资源; 它可以调用终结器,如果它是你清理代码的因素.
从技术上讲,它们可以在逻辑上用一个简单的布尔保护来阻止它
是的,因为所有的清理都应该完成,所以你要求CLR不要完成对象
是的,因为基类知道它分配了哪些资源
是的,这是用于确定性清理
你应该确保它是这样的
其他人:
是的~MyClass映射到Finalize方法的覆盖
如上所述,析构函数映射到Dispose,但您应该自己实现终结器:!MyClass
简介:C++析构函数和Dispose模式用于确定性清理,C#析构函数,C++/CLI终结器用于由GC触发的非确定性清理.