Visual C ++不受管理和管理

时间:2011-04-06 17:59:17

标签: visual-c++ pointers memory-management c++-cli

在C ++中创建.NET对象的实例与托管和非托管之间有什么区别。也就是说,这些与声明之间的区别是什么:

StreamWriter ^stream = gcnew StreamWriter(fileName);

StreamWriter *stream = new StreamWriter(fileName);

我的假设是,如果我使用gcnew,为StreamWriter分配的内存将由垃圾收集器管理。或者,如果我使用指针(*)和new关键字,我将不得不调用delete来释放内存。

我真正的问题是:垃圾收集器是否会管理在.NET对象内部分配的内存?例如,如果.NET对象实例化另一个对象,并且它超出范围 - 即使我使用指针(*)和new关键字而不是gcnew和handle(^),垃圾收集器也会管理该内存。

2 个答案:

答案 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_ptrstd::unique_ptr)来管理本机堆上的对象。但是,由于您不能将本机智能指针作为ref类的字段,因此这并不完全是直截了当的。最简单和最通用的方法可能是编写自己的智能指针包装器ref类,它正确实现IDisposable

答案 1 :(得分:4)

使用 gcnew 创建对象时,它会绑定到垃圾收集器,垃圾收集器将负责销毁它。

如果您使用 new ,它将不会被绑定到垃圾收集器,您将有责任删除该对象。

只是为了澄清:
如果您有一个托管C#对象,其中包含一个非托管对象,则垃圾回收器不会删除非托管对象。它只会在删除之前调用托管对象的析构函数(如果存在)。您应该在析构函数中编写自己的代码以删除您创建的非托管对象。