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

Omn*_*ous 17 c++ scope memory-management software-design c++11

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

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

Fre*_*Foo 22

C++功能之一,使其与其他语言区别开来

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

  • 当一个对象必须长寿时分配在堆上,即必须比某个范围寿命长,并且昂贵或不可能复制或移动,
  • 在一个对象很大的时候在堆上进行分配(如果你想要安全的话,那么大可能意味着几千字节)以防止堆栈溢出,即使该对象只是暂时需要,
  • 如果您正在使用pimpl(编译器防火墙)习惯用法,则在堆上进行分配,
  • 在堆上分配可变大小的数组,
  • 否则在堆栈上分配,因为它更方便.

请注意,在第二个规则中,"大对象"我的意思是

char buffer[1024 * 1024];  // 1MB buffer
Run Code Online (Sandbox Code Playgroud)

但不是

std::vector<char> buffer(1024 * 1024);
Run Code Online (Sandbox Code Playgroud)

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

至于指针与值成员:

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

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

  • +1,但我想我们应该提到[RVO](http://en.wikipedia.org/wiki/Return_value_optimization)作为你的第一点.那个在很多情况下你的两个点都是真的,仍然可以在堆栈上分配(即一些辅助函数返回一些对象). (4认同)