如何在 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.
相关文章