C++ 什么时候应该在堆栈而不是堆上分配类
过去,每当我需要创建一个类的实例时,我都会使用new在堆上分配它(stl类和vec3和mat4等数学类除外) 然而,我只是在批判性地查看我的一些代码,并意识到从技术上讲,我可以在堆栈上生成这些类。它们不是很大,不需要在当前范围之外进行修改,等等。当我(偶尔)需要将它们传递给另一个函数时,我可以像传递指针一样轻松地使用引用 在过去,我总是默认在堆上分配,并且只在某些情况下使用堆栈,但是现在我想知道,如果默认在堆栈上分配,并且只在以下情况下使用堆,是否会更好C++ 什么时候应该在堆栈而不是堆上分配类,c++,C++,过去,每当我需要创建一个类的实例时,我都会使用new在堆上分配它(stl类和vec3和mat4等数学类除外) 然而,我只是在批判性地查看我的一些代码,并意识到从技术上讲,我可以在堆栈上生成这些类。它们不是很大,不需要在当前范围之外进行修改,等等。当我(偶尔)需要将它们传递给另一个函数时,我可以像传递指针一样轻松地使用引用 在过去,我总是默认在堆上分配,并且只在某些情况下使用堆栈,但是现在我想知道,如果默认在堆栈上分配,并且只在以下情况下使用堆,是否会更好 确实需要一个指针(即对象的生存期超过声
- 确实需要一个指针(即对象的生存期超过声明的范围)
- 类或数组对于堆栈来说太大
- 继承需要它(抽象基类/接口)
- 还有别的吗
这也提出了一个问题:一个类有多大(粗略地)太大而无法在堆栈上合理分配?(假设我们至少在开发智能手机,并逐步升级到高端台式机)我只是不必要地担心堆栈大小限制吗?(可能,只要我们不是在讨论大型数组,而且没有一个类会接近千字节)只有在需要动态分配内存时才在堆上进行分配。这意味着您不知道在编译时需要分配多少。
您在堆栈上分配所有其他时间出于两个原因,我更喜欢在堆栈上分配。首先,在所有其他条件相同的情况下,它比heap更快。而且,解除分配是自动发生的,我不需要记住删除它(当然,有自动解除分配之类的帮助) 确实需要一个指针 可以将指针传递到堆栈上的对象。只需确保该指针的用户在其生存期到期后不会访问该对象 类或数组对于堆栈来说太大 只有在真正重大的事情上,这才重要。您可能有1MB的堆栈,因此可以在出现问题之前放置大约1000个1KB的对象 继承需要它 为什么会这样 还有别的吗
对象所需的生存期长于堆栈帧的生存期。这是在堆上进行分配的主要原因。您的默认行为应该是: 如果对象的寿命与特定范围一致
ie在编译时很容易确定 然后它应该是一个自动存储持续时间对象(类似堆栈) 如果对象的寿命是在运行时定义的,并且超出了当前范围 然后它应该是一个动态存储持续时间对象(类似于堆) 注意:所有动态存储持续时间对象都应该通过将其包装到适当的RAII类中来控制其寿命。通常这意味着:对于单个对象,一个智能指针,而多个对象最终位于一个容器中 我讨厌看到事物定义为堆栈与堆。因为它不能传达情况的真正语义
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.
您应该考虑自动/动态“存储持续时间”对象。这传达了语言的正确语义
注意,还有两种其他类型的变量,因此有四种不同类型的变量。自动/动态/静态/线程“存储持续时间”对象
什么时候应该在堆栈而不是堆上分配类
只要有可能,并不是很大的不便。当然也有例外,但作为一般规则回答您的问题:创建实例时,new
/new[]
的键入时间应少于1%
确实需要一个指针(即对象的生存期超过声明的范围) 是的,在适当的情况下。从您对OP中描述的堆的使用来看,这可能比您认为的要少很多 类或数组对于堆栈来说太大 是的,但是这不应该引起太大的关注——一个如此大的类通常表明您的类存在根本性的问题。客户端友好类可以考虑在堆上创建那些巨大的、固定大小的数组。 继承需要它(抽象基类/接口)
在某些情况下(例如,存在一个抽象工厂或多态性克隆的深度克隆),但是它是创建该类型的工厂,并且在您可以考虑它之前,该问题经常偏离您的程序的使用。 还有别的吗
没有原因是:
- 它清晰、简洁,并且它的生命周期和范围已经确定
- 减少资源消耗
- 更少的内存相关错误或可能出错的事情
- 速度。堆栈分配非常快。更少的锁