c++ - Visual C++ native 内存管理最佳实践

标签 c++ visual-c++ memory-management

我是一名老 C# 程序员和一名 C 程序员(没有动态内存分配),但想学习一些有关 Visual C++ 编程的知识。困扰我的问题与 C++ 中的内存管理有关。在 C# 中,垃圾收集器负责内存管理,但在 C++ 中,有必要针对谁负责释放分配的内存建立一些规则。我有一些来自 C# 的典型场景:

  1. 对象被放入某种容器中。谁负责释放内存。如果多个类共享同一个对象怎么办?

  2. 工厂模式。我喜欢使用类的层次结构,其中父类具有创建子对象的方法?

  3. 有没有办法向调用方法建议返回的对象是被调用者/调用者的所有权。

我想听听一些关于这方面的好建议。

最佳答案

如果您正确编写代码,就不必担心这个问题,至少不会直接担心。有一些库设施可供您使用,它们可以完全自动地为您处理内存管理和其他资源管理,因此您不必这样做。

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/

相关文章:

c++ - MSVC预编译头: Which files need to #include "stdafx.h"?

c++ - 下面这段代码会把内存分配到哪里?

c++ - 为什么找不到一个Visual Studio#包含两个文件?

c++ - 在容器元素上应用函数需要更好的名称

c++ - 关闭我的 DISLIN 小部件会导致我的整个程序关闭

C++模板类继承

c - 将内存动态分配给结构节点数组

c++ - 使用带有 vector 作为成员变量的类的boost内存池

c++ - 如何在预处理器中检测 -stdlib=libc++?

c++ - 从模板继承?