我是一名老 C# 程序员和一名 C 程序员(没有动态内存分配),但想学习一些有关 Visual C++ 编程的知识。困扰我的问题与 C++ 中的内存管理有关。在 C# 中,垃圾收集器负责内存管理,但在 C++ 中,有必要针对谁负责释放分配的内存建立一些规则。我有一些来自 C# 的典型场景:
对象被放入某种容器中。谁负责释放内存。如果多个类共享同一个对象怎么办?
工厂模式。我喜欢使用类的层次结构,其中父类具有创建子对象的方法?
有没有办法向调用方法建议返回的对象是被调用者/调用者的所有权。
我想听听一些关于这方面的好建议。
最佳答案
如果您正确编写代码,就不必担心这个问题,至少不会直接担心。有一些库设施可供您使用,它们可以完全自动地为您处理内存管理和其他资源管理,因此您不必这样做。
C++ 提供了比垃圾收集器更好的东西:它提供了所有对象的确定性销毁,并且确定性销毁可用于自动管理每个资源的生命周期,不像垃圾收集(在许多常见的实现中)只允许你自动管理内存,并让您手动管理所有其他需要确定性清理的资源。
如果你动态分配一个对象,使用智能指针来管理它的生命周期。如果您不需要共享所有权,那么您可以使用 std::unique_ptr
,它允许您将所有权从一个所有者转移到另一个所有者。如果您确实需要共享所有权,您可以使用 std::shared_ptr
,它使用引用计数技术来维护共享所有权。
有两个重要的规则要牢记:
如果你必须写
delete
在您的 C++ 程序中,代码几乎肯定是错误的。 C++ 为所有资源(包括内存)提供自动生命周期管理,您应该利用它。唯一的地方delete
应该出现在实现资源拥有容器的库代码中,并且可能出现在更罕见的低级代码中。尽可能优先处理对象,而不是指向对象的指针。应尽可能避免显式动态分配。 C++ 不像 C# 和 Java 这样的语言,后者的大多数对象都是在堆上创建的。在 C++ 中,在堆栈上创建对象(使用自动变量)并按值返回它们通常更好。
回答您的具体情况:
Object is put in a container of some kind. Who is responsible for freeing the memory. What if several classes share the same object?
只要有可能,您应该更喜欢将对象本身存储在容器中,而不是指向对象的指针。如果你出于某种原因确实需要存储指向对象的指针,你应该使用智能指针的容器(例如 std::vector
)。如果容器拥有动态分配对象的唯一所有权,您可以使用 std::vector<std::unique_ptr<T>>
;如果容器要共享对象的所有权,您可以使用 std::vector<std::shared_ptr<T>>
.
Factory pattern. I like using a hierarchy of classes, where the parent class has a method for creating child objects?
这与前面的场景没有什么不同:如果你有一棵树,使用 std::vector<T>
就很简单了。 (或者 std::vector<std::unique_ptr<T>>
如果您需要动态分配的 child )拥有 child 。
Is there a way to suggest to the calling method that the returned object is in ownership of the callee/caller.
如果对象完全由被调用者拥有(例如在 std::unique_ptr
中),那么您可以返回该智能指针;这样做会将所有权转移给调用者。
如果存在对象的共享所有权(例如在 std::shared_ptr
中),则返回智能指针将使调用者成为所有者之一;最后一个所有者放弃其所有权(通过销毁或以其他方式重置其拥有该对象的 std::shared_ptr
)会自动销毁该对象。
关于c++ - Visual C++ native 内存管理最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4963610/