为什么我会在堆中禁止分配?

时间:2010-08-19 12:24:21

标签: c++ class stack memory-management heap

我最近阅读了很多关于“防止课程堆分配”的内容(参见this question)。

我能够理解“how”,但现在我无法弄明白“为什么”有人愿意这样做。

我想这一定有合理的理由,但我无法弄明白。

简而言之:“为什么我要禁止用户在堆中创建我的类的对象?”

6 个答案:

答案 0 :(得分:13)

只有在堆栈上实例化对象时,某些类才有意义。例如,提升scoped_ptrlock_guard

答案 1 :(得分:5)

主要是因为堆栈分配的对象在超出范围时会自动清理,从而消除了一大类错误 - 即内存分配错误。

答案 2 :(得分:4)

我会反对看似潮流(所以我确实期望downvotes,但请留下评论以说明原因)。

我认为没有理由禁止堆分配,主要是因为我不想再猜测我创建的类的潜在用途。

作为一个设计规则,我倾向于尽可能少地限制我的类的使用。这意味着尽可能少的假设。没有什么比不能做你想做的事情更令人抓狂,因为它被禁止了......原因不明或只是错误(表示图书馆作家的迷信/错误信念)。

此外,实用主义教导说,实际上阻止 C ++中的任何事情都是不可能的。例如,有些人谈到了警卫 - >如果我想创建一个超类(方便地添加日志记录)怎么办?然后我将保护类作为属性,即使它(原始类)new运算符是私有的,我的超类也可以在堆上实例化,除非它以某种方式复制机制。

所以,对我来说,这不是为什么或如何。我只是不想在库代码中使用内存分配方案,而是由用户使用对她来说最方便的内容。

答案 3 :(得分:2)

通常最好防止类的意外使用。例如,考虑依赖RAII技术的Guard类。它们必须在堆栈上分配,并且当它们超出范围时它们就能完成它们的工作。没有人希望用户在堆中分配保护对象,因此明确禁止它。

比隐式更明确。 Herb Shutter说,必须很难错误地使用你的类(在堆中分配)并且很容易正确使用它(在堆栈中)。

答案 4 :(得分:1)

堆栈分配更快(不需要搜索空间)。

答案 5 :(得分:0)

对于某些非常小的对象类 - 考虑几何引擎中的3D点 - 在堆上单独分配这些点是创建悬空指针和引入大量开销的一个方法 - 但是,它们在很多方面都是非常必要的。计算

因此,一种常见的机制是在实际包含3D点集合的对象中使用flyweight模式,例如某些几何实体的描述,并允许它们在堆上用作计算的中间结果。

现在,这就是说,需要特别注意避免在flyweight实现之间不必要地复制数据,例如ListOf3DPoints和堆分配的3D点用于中间结果。

总的来说,我发现了一些案例,我将flyweight模式与堆分配功能相结合,以实现最佳结果 - flyweight提供持久存储,堆分配让我可以执行项目级操作而无需生成另一个轻量级