Visual C++无人管理和管理

Min*_*wth 6 pointers memory-management c++-cli visual-c++

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

StreamWriter ^stream = gcnew StreamWriter(fileName);
Run Code Online (Sandbox Code Playgroud)

StreamWriter *stream = new StreamWriter(fileName);
Run Code Online (Sandbox Code Playgroud)

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

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

Jam*_*lis 6

在C++/CLI中,您不能new使用.NET对象,您将获得类似于以下错误的内容:

错误C2750:'System :: Object':不能在引用类型上使用'new'; 请改用'gcnew'

new旧的Managed Extensions for C++(/clr:oldsyntax编译器标志)允许使用.NET对象."Managed C++"现已被弃用,因为它太可怕了.它已被C++/CLI取代,它引入了^gcnew.

在C++/CLI中,必须对托管类型使用gcnew(和^处理),并且必须对本机类型使用new(和*指针).如果您确实使用本机堆创建对象new,则在完成它们时,您有责任销毁它们.

理想情况下,您应该使用智能指针(如std::shared_ptrstd::unique_ptr)来管理本机堆上的对象.但是,由于您不能将本机智能指针作为ref类的字段,因此这并不完全是直截了当的.最简单和最通用的方法可能是编写正确实现的自己的智能指针包装器ref类IDisposable.

  • @casablanca:你不能使用`new`来创建一个托管对象,句号.在C++/CLI中根本不允许使用`new StreamWriter(fileName)`. (2认同)

Yoc*_*mer 4

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

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

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