我对C++/CLI中的资源管理感到非常困惑。我以为自己已经掌握了这个知识点,但是在查看头文件时,我发现了auto_gcroot<T>
类,于是进行了谷歌搜索、整整一天的阅读文档,但现在仍然感到困惑。因此我决定向社区求助。
我的问题涉及auto_handle/stack语义和auto_gcroot/gcroot之间的区别。
auto_handle: 我理解的是它可以清理由托管函数创建的托管对象。但我困惑的是,垃圾回收器难道不应该替我们完成这个工作吗?这不是托管代码的全部意义吗?更具体地说:
//Everything that follows is managed code void WillThisLeak(void) { String ^str = gcnew String ^(); //Did I just leak memory? Or will GC clean this up? what if an exception is thrown? } void NotGoingToLeak(void) { String ^str = gcnew String^(); delete str; //Guaranteed not to leak, but is this necessary? } void AlsoNotGoingToLeak(void) { auto_handle<String ^> str = gcnew String^(); //Also Guaranteed not to leak, but is this necessary? } void DidntEvenKnowICouldDoThisUntilToday(void) { String str(); //Also Guaranteed not to leak, but is this necessary? }
如果这是替代C# using关键字的东西,并且只建议在使用资源密集型类型(如位图)时使用,那么这将对我有意义,但文档中没有提到,所以我担心自己一直在泄漏内存。
auto_gcroot
我能把它作为参数传递给本地函数吗?复制时会发生什么?
void function(void)
{
auto_gcroot<Bitmap ^> bmp = //load bitmap from somewhere
manipulateBmp(bmp);
pictureBox.Image = bmp; //Is my Bitmap now disposed of by auto_gcroot?
}
#pragma unmanaged
void maipulateBmp(auto_gcroot<Bitmap ^> bmp)
{
//Do stuff to bmp
//destructor for bmp is now called right? does this call dispose?
}
如果我使用 gcroot 代替 auto_gcroot,这个代码会起作用吗?
此外,auto_handle 和 auto_gcroot 有什么优点?它们似乎做了类似的事情。
我一定误解了某些东西,所以需要一个好的解释。另外,关于这些类型的正确使用方法、学习这些内容的地方以及更多的最佳实践/可以找到它们的地方的任何指导都将不胜感激。
非常感谢, Max
gcroot
,但很少(当我想将.NET闭包/委托包装到C++函数对象中并确保保持句柄尽可能长时间时)。 - Alexandre C.