类 应该自己管理动态内存吗?

Should classes manage dynamic memory on their own?

如果 class 需要动态分配内存(例如 std::vector),class 可以使用运算符 [=12 简单地在内部分配和释放内存吗? =] 或 malloc?

答案对我来说不是很明显。缺少像垃圾收集语言那样管理内存分配的系统显然是一种授权;但另一方面,恰恰是这种不协调导致了内存的浪费。例如,制作一个 'fake' 分配器只是将堆栈内存传递给一个对象,这在正常情况下需要动态内存,但程序员可以断言永远不会需要超过 X 的内存量。字节。

也许你认为这个问题在大地址空间的时代无关紧要,但退回到硬件上感觉有点蹩脚,毕竟这是C++。

编辑

我现在意识到我对这个问题的含糊其辞......让我解释得更好一些。

当我说 'wasting memory' 时,我特别指的是堆碎片造成的内存浪费。减少堆碎片是在 C++ 中创建内存管理系统最引人注目的一点,因为(正如许多评论所指出的那样)析构函数已经处理了资源管理方面的事情。当你的分配基本上是随机的(你不知道你的新内存相对于其他分配内存的位置)并且每个 class 都可能分配时,你 运行 会遇到面向数据设计的问题尝试修复:数据局部性差。

所以问题是:class 进行内存管理、对象管理、堆压缩以及可能的统计跟踪(用于调试目的)以使最有效使用内存和数据局部性?

[在这种情况下,每个 class 或动态分配内存的函数都必须以某种方式获得对该 class 的引用。]

或者让每个 class 都能够分配而不必使其 成为 class 接口的一部分更好吗?

If a class needs to allocate memory dynamically (e.g. std::vector), is it acceptable for the class to simply allocate and deallocate the memory internally, using operator new or malloc?

通常我们有两种classes:

  • 资源管理器(包括动态内存);
  • “业务逻辑”classes.

大多数时候我们shouldn't mix the layers of resource management and domain logic

因此,如果您的class是原始资源的管理者,它allocates/deallocates,initializes/deinitializes 它的 只有 资源,什么都不做。在这种情况下, new 是可以的,甚至是必要的(例如,在编写自己的动态数组时不能改用 std::vector ,否则根本不需要编写它)。参见 RAII

如果您的 class 包含一些应用程序逻辑,则不允许显式分配动态内存、打开套接字等., 但它为此使用其他 RAII-classes。在这个高层次上,C++ 为您提供了 GC 语言所没有的东西:它让 RAII 所有者管理文件、套接字等 - 任何类型的资源,而不仅仅是堆内存的原始字节,因此您不需要手动 Java/C#-style try-with-resources 在任何你创建非原始内存管理器对象的地方 - 只要你有一个 RAII class,编译器就会为你做它。