在C ++中创建.NET对象的实例与托管和非托管之间有什么区别。也就是说,这些与声明之间的区别是什么:
StreamWriter ^stream = gcnew StreamWriter(fileName);
与
StreamWriter *stream = new StreamWriter(fileName);
我的假设是,如果我使用gcnew,为StreamWriter分配的内存将由垃圾收集器管理。或者,如果我使用指针(*)和new关键字,我将不得不调用delete来释放内存。
我真正的问题是:垃圾收集器是否会管理在.NET对象内部分配的内存?例如,如果.NET对象实例化另一个对象,并且它超出范围 - 即使我使用指针(*)和new关键字而不是gcnew和handle(^),垃圾收集器也会管理该内存。
答案 0 :(得分:6)
在C ++ / CLI中,你不能new
一个.NET对象,你会得到类似于以下错误:
错误C2750:'System :: Object':不能在引用类型上使用'new';使用'gcnew'代替
旧的Managed Extensions for C ++(new
编译器标志)允许使用/clr:oldsyntax
用于.NET对象。 “Managed C ++”现已被弃用,因为它太可怕了。它已被C ++ / CLI取代,它引入了^
和gcnew
。
在C ++ / CLI中,必须对托管类型使用gcnew
(和^
句柄),并且必须对本机类型使用new
(和*
指针)。如果您使用new
在本机堆上创建对象,则在完成它们时,您有责任销毁它们。
理想情况下,您应该使用智能指针(如std::shared_ptr
或std::unique_ptr
)来管理本机堆上的对象。但是,由于您不能将本机智能指针作为ref类的字段,因此这并不完全是直截了当的。最简单和最通用的方法可能是编写自己的智能指针包装器ref类,它正确实现IDisposable
。
答案 1 :(得分:4)
使用 gcnew 创建对象时,它会绑定到垃圾收集器,垃圾收集器将负责销毁它。
如果您使用 new ,它将不会被绑定到垃圾收集器,您将有责任删除该对象。
只是为了澄清:
如果您有一个托管C#对象,其中包含一个非托管对象,则垃圾回收器不会删除非托管对象。它只会在删除之前调用托管对象的析构函数(如果存在)。您应该在析构函数中编写自己的代码以删除您创建的非托管对象。