【发布时间】:2014-09-16 09:45:05
【问题描述】:
当您在 ref 类上实现析构函数时,C++/CLI 会为您生成 IDisposable 脚手架。此外,如果您没有实现析构函数,但您的类有一个实现IDisposable 的成员变量,那么IDisposable 将再次在您的类上自动实现。这比在 C# 中处理 IDisposable 的方式非常有用,而且要好得多。
我在实现一个持有msclr::com::ptr(一个包含RCW的智能指针)的引用类时遇到了这种行为。
ref class Test /* : IDisposable added by the compiler */
{
msclr::com::ptr<IWhatever> _aComObject;
}
在我的具体情况中,我的类引用的 COM 对象不会“锁定”一些非托管资源,它实际上只是占用了 CLR 看不到的一些非托管内存。因此,我想通过不实现 IDisposable 类来避免混淆我的 ref 类的用户。相反,我想通过使用 GC API 添加适当的内存压力,让 CLR 知道 COM 对象的存在。
所以,问题是:有没有办法在一个没有实现析构函数但持有一个IDisposable 成员变量的引用类上抑制IDisposable 的实现?
注意:这通常是错误的做法,因为它会阻止该类的用户确定性地处置底层 COM 对象,但考虑到特定情况,暴露 IDisposable 有可能会混淆我的 ref 类的用户,因为确实没有必要 Dispose 有问题的 ref 类。
我想一种选择是在没有析构函数的情况下实现 msclr::com::ptr 的变体。
任何其他禁止自动添加 IDisposable 的方法将不胜感激。谢谢。
回答
将 _aComObject 声明为 msclr::com::ptr (msclr::com::ptr<IWhatever>^) 的句柄。编译器不会将Test 视为该com ptr 对象的“所有者”,并且不会在删除Test 时将其Dispose。
【问题讨论】:
-
您打算什么时候对 com 对象调用 release 并消除内存压力 - 这些东西通常都在 dispose 调用中进行管理?
-
@morechili:如果没有以确定性方式显式处理,它会以非确定性方式自动发生(我想当 COM 对象的 RCW 变成垃圾并最终确定时)。跨度>
-
因此我会说将您的对象保留为 IDisposable 更为正确。让客户选择或不选择确定性行为。它是一次性对象,它正在使用非托管资源。我担心那个人。 c++ 正在执行正确的规则,隐藏它们就是隐藏潜在的问题。
-
@morechilli - 我想我已经足够解释为什么我想做我想做的事了。我期望得到响应(IDisposable 是使用非托管资源时唯一可能做的正确事情),并尝试在问题中处理它。
-
对该问题+1,只是为了“它非常有用,而且比 C# 中的 IDisposable 处理方式要好得多。”
标签: c++-cli idisposable