何时应该在堆栈而不是堆上分配类

zac*_*caj 11 c++

在过去,每当我需要创建一个类的实例时,我都会使用new在堆上分配它(除了stl类和数学类,如vec3和mat4).

但是,我只是批评我的一些代码,并意识到技术上我可以只是在堆栈上制作这些类.它们不是很大,不需要在当前范围之外进行修改等.当我(偶尔)需要将它们传递给另一个函数时,我可以像使用指针一样轻松地使用引用.

在过去,我总是默认在堆上进行分配,并且在某些情况下仅使用堆栈,但是现在我想知道默认情况下在堆栈上分配是否更好,并且仅在使用堆时

  • 确实需要一个指针(即对象的生命周期超出声明范围)
  • 类或数组对于堆栈来说太大了
  • 继承需要它(抽象基类/接口)
  • 别的什么?

这也提出了一个问题:一个类有多大(大致)在堆栈上合理分配?(假设我们正在努力,至少是智能手机,并进入高端桌面)我只是担心不必要的堆栈大小限制?(可能,只要我们不讨论大型数组,并且没有类甚至接近千字节)

Mar*_*ork 7

您的默认行为应该是:

如果对象的生命周期与特定范围一致,
即在编译时容易确定

那么它应该是一个自动存储持续时间对象(像堆栈一样)

如果对象的生命周期是在运行时定义的并且超出了当前范围

那么它应该是一个动态存储持续时间对象(堆像)

注意:所有动态存储持续时间对象应通过将它们包装在适当的RAII类中来控制其生命周期.通常这意味着:对于单个对象,智能指针,而多个对象最终在容器中.

讨厌将事物定义为堆栈Vs堆.因为它没有传达情况的真实语义.

 int x;       // its on the stack
 struct X
 {
     int x;   // Is this a stack or heap object?
 }            // It depends on its parent.


 // But in both cases it is an automatic storage duration object.
 // In both cases the lifespan's are well defined.
 //     The first is defined by the scope it is declared within.
 //     The second is defined by the lifespan of its parent.
Run Code Online (Sandbox Code Playgroud)

您应该考虑自动/动态"存储持续时间"对象.这传达了语言的正确语义.

注意,还有另外两种类型的变量,从而产生四种不同类型的变量.自动/动态/静态/线程'存储持续时间'对象.


Kei*_*all 5

我更喜欢在堆栈上分配,有两个原因。首先,在其他条件相同的情况下,它比堆更快。另外,释放是自动发生的,我不需要记住它delete(当然,有auto_ptrs 之类的东西可以帮助做到这一点)。

确实需要一个指针

可以将指针传递给堆栈上的对象。只需确保该指针的用户在其生命周期到期后不会访问该对象。

类或数组对于堆栈来说太大

只有对于真正重大的事情这才重要。您可能有 1MB 的堆栈,因此您可以在出现问题之前放置大约 1000 个 1KB 对象。

继承需要它

为什么会这样?

还有别的东西吗?

对象所需的生命周期比堆栈帧的生命周期长。这是在堆上分配的主要原因。