如何在 C++ 中选择堆分配与堆栈分配?

将其与其他语言区分开来的 C++ 特性之一是能够将复杂对象分配为成员变量或局部变量,而不必总是使用 new 分配它们.但这会导致在任何给定情况下选择哪个的问题.

One of the C++ features that sets it apart from other languages is the ability to allocate complex objects as member variables or local variables instead of always having to allocate them with new. But this then leads to the question of which to choose in any given situation.

是否有一些很好的标准来选择如何分配变量?什么时候应该将成员变量声明为直接变量而不是引用或指针?什么时候应该使用 new 分配变量而不是使用分配在堆栈上的局部变量?

Is there some good set of criteria for choosing how to allocate variables? When should I declare a member variable as a straight variable instead of as a reference or a pointer? When should I allocate a variable with new rather than use a local variable that's allocated on the stack?

推荐答案

将其与其他语言区分开来的 C++ 特性之一

One of the C++ features that sets it apart from other languages

... 是您必须手动分配内存.但让我们把它放在一边:

... is that you have to do memory allocation manually. But let's leave that aside:

  • 当一个对象必须是长期存在的,即必须超过某个范围,并且复制或移动成本高昂或不可能时,在堆上分配,
  • 当对象很大时(如果你想安全起见,大可能意味着几千字节)在堆上分配以防止堆栈溢出,即使对象只是暂时需要,
  • 如果您使用的是 pimpl(编译器防火墙)习惯用法,请在堆上分配
  • 一>,
  • 在堆上分配可变大小的数组,
  • 否则在堆栈上分配,因为它更方便.

请注意,在第二条规则中,大对象"是指类似

Note that in the second rule, by "large object" I mean something like

char buffer[1024 * 1024];  // 1MB buffer

但不是

std::vector<char> buffer(1024 * 1024);

因为第二个实际上是一个非常小的对象,它包装了一个指向堆分配缓冲区的指针.

since the second is actually a very small object wrapping a pointer to a heap-allocated buffer.

关于指针与值成员:

  • 如果需要堆分配,请使用指针,
  • 如果要共享结构,请使用指针,
  • 使用指针或引用来实现多态性,
  • 如果您从客户端代码中获取对象并且客户端承诺保持它的活动状态,请使用引用,
  • 在大多数其他情况下使用一个值.

当然建议在适当的情况下使用智能指针.请注意,您可以在堆分配的情况下使用引用,因为您始终可以delete &ref,但我不建议这样做.引用是伪装的指针,只有一个区别(引用不能为空),但它们也表示不同的意图.

The use of smart pointers is of course recommended where appropriate. Note that you can use a reference in case of heap allocation because you can always delete &ref, but I wouldn't recommend doing that. References are pointers in disguise with only one difference (a reference can't be null), but they also signal a different intent.

相关文章