首页 > 解决方案 > 是否所有 C++/CLI 对象都需要处理?

问题描述

我的理解(部分来自阅读此处的线程)是世界上的每个 C++/CLI 对象都通过其 C++/CLI 析构函数自动实现 IDisposable。

我的进一步理解是,每当您的托管类 A 使用另一个实现 IDisposable 的托管类 B 的实例时,您就有责任在某处实现 IDisposable (或使用“使用”语句)以确保调用 B.Dispose。

这两个都对吗?如果是这样,那么这意味着基本上每当我在 C# 代码的任何地方使用 C++/CLI 对象时,我都需要 IDisposable 实现或使用来清理它。是的?

这我没有意识到

在我当前的应用程序设计中,我的 C# 类都没有真正“拥有”它们使用的任何 C++/CLI 对象实例。我倾向于自由地创造和传递它们。“A”类的 AC# 对象可能会创建一个 C++/CLI 对象,然后将其交给 C# 类“B”和“Z”的实例。所有 3 都可能存储对它的引用所以他们都不能调用 Dispose 因为他们都没有拥有它。

如此有效地,我有一大堆 IDisposable C++/CLI 对象,没有人对它们调用 Dispose。

我以为这很好。只有少数我的 C++/CLI 类分配了很大一部分内存。

这是我应该关心的吗?我是否应该尝试重新构建我的应用程序,以便每个 C++/CLI 对象都由一个且只有一个 C# 对象拥有,以便我可以在 C# 类上实现 IDisposable 并尽职尽责地在底层 C++/CLI 实例上调用 Dispose?

标签: .netc++-cliidisposable

解决方案


简短的回答是“不”,所有 CLI 类都不需要处理。仅当非托管资源发挥作用​​时才需要处置。例如,在非托管堆上分配的文件句柄或内存。

编辑...

我不相信“世界上每个 C++/CLI 类都通过设计实现 IDisposable”是正确的说法。可以准确地说“每个声明终结器的 C++/CLI 类都实现 IDisposable”。在 C++ 中,当你delete是一个托管对象时,它的析构函数被调用,而它又应该调用它自己的终结器。当在 C#(例如)中调用Dispose()(显式或通过using块)时,将调用其终结器,这实际上意味着它实现了 IDisposable。如果没有终结器,则无法从 C# 等语言正确处置对象。

https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ms177197(v=vs.100)


推荐阅读