感谢您的关注。我是一些VS2013代码的新手,它是C ++和一些微软特定扩展的混合体。代码有类似
的类ref class Foo {
Bar^ bar_; // somewhere else, bar_ = gcnew Bar...
};
现在我需要添加一个非托管成员,从在线搜索看来我似乎可以做到
ref class Foo {
Bar ^ bar_;
Unmanaged* ptr_; // somewhere else, ptr = new Unmanaged();
~Foo() {
this->!Foo();
}
!Foo() {
delete ptr_;
// do I need anything to deal with bar_?
}
};
问题是:
1)这个终结器/析构器是要走的路吗?
2)我是否需要为bar_
编写额外的内容,因为我明确写了终结器/析构函数?
3)有更干净的方法吗?
答案 0 :(得分:3)
1)这个终结器/析构器是要走的路吗?
是
2)我是否需要为bar _
编写额外的内容
片段中没有任何明显的内容。但是如果Bar类也是一次性的,那么你可能应该将delete bar_;
添加到析构函数中。不是终结者。如果您将引用传递给其他代码,那么就不能确定此引用是最后一个仍使用Bar对象的引用。
3)有更干净的方法吗?
没有。有其他方法可以做到这一点。例如,您可以考虑不添加析构函数。有一个给使用该类的代码调用它的负担。通常情况下,这将是C#或VB.NET代码,它必须使用using
语句或显式调用Dispose()。请记住,他们经常忘记。或者没有一个好方法来打电话。
如果不希望这样的代码创建很多Foo实例,而Unmanaged类只使用一点内存,那么终结器可能就足够了。或者,如果Foo对象预计会在应用程序的生命周期中存活,这很常见,那么处理是没有意义的。即使它确实使用了大量内存,GC :: AddMemoryPressure()也是一个非常好的选择。使您的课程更容易使用。
你可以考虑将Unmanaged指针包装在它自己的类中,这样Foo就不再需要终结器了。沿着.NET中的SafeHandle类的模式,SafeBuffer是最接近的匹配。这往往是矫枉过正,但在C ++ / CLI包装器中,delete
失败尤其不是你想要隐藏的。
但是你所拥有的就完成了工作。