何时以及为何在堆C ++上声明成员变量

时间:2012-07-13 19:59:28

标签: c++ class heap member-variables

好的,所以我对C ++编程非常陌生,而且我已经四处寻找一个决定性的答案了。什么时候我应该在堆与堆栈上声明成员变量?我发现的大多数答案都涉及其他问题,但我想知道何时最好将堆用于成员变量,以及为什么最好堆叠成员而不是堆叠它们。

5 个答案:

答案 0 :(得分:19)

首先要掌握两个重要概念:

  1. 应该避免考虑“堆”和“堆栈”。这些是编译器/平台的实现细节,而不是语言的实现细节。 1 相反,请考虑对象生存期:对象的生命周期是否与其“父对象”的生命周期相对应“或者它应该比它活得更久?如果您需要后者,那么您需要使用new(直接或间接)动态分配对象。

  2. 成员变量始终与其父级具有相同的生命周期。成员变量可以是指针,它指向的对象可能具有独立的生命周期。但是指向的对象不是成员变量。

  3. 但是,您的问题没有一般性答案。粗略地说,除非有充分的理由,否则不要动态分配。正如我上面所暗示的,这些原因通常对应于生命周期需要与其“父母”不同的情况。

    <小时/> <子> 1。实际上,C ++标准并没有真正谈论“堆”和“堆栈”。在优化或一般考虑性能时,它们很重要,但从程序功能的角度来看,它们大多无关紧要。

答案 1 :(得分:4)

成员变量是类本身的成员。他们都不在 堆也不在堆栈上,或者更确切地说,它们是类的所在 本身就是。

添加间接级别并分配a的原因很少 成员分别在堆上:多态(如果成员的类型 并不总是相同的)是迄今为止最常见的。

答案 2 :(得分:2)

直接获得一些术语:您称之为heapstack的内容描述了对象的生命周期。第一个意味着生命周期为dynamic,第二个automatic和第三个(您未提及)为static

通常,当对象的生命周期超过其创建范围时,您将需要dynamic生命周期。另一种常见情况是,您希望它在不同的父对象之间共享。此外,当您使用面向对象的设计(使用大量多态,不使用值)时,动态生命周期也是必要的。 Qt

需要动态生命期的成语是pimpl-idiom。

大多数通用编程库更侧重于价值和价值语义,所以你不会使用那么多的动态绑定,自动生命周期变得更加普遍。

还有一些示例需要动态分配,以满足更多特定于实现的原因:

  • 动态大小的对象(容器)
  • 处理不完整类型(参见pimpl-idiom)
  • 类型易于引用

所有这些只是一般指导原则,必须根据具体情况决定。通常,更喜欢自动对象而不是动态对象。

答案 3 :(得分:1)

堆栈是指call stack。函数调用,返回地址,参数和局部变量保留在调用堆栈中。无论何时传递参数或创建局部变量,都使用堆栈内存。堆栈只有临时存储空间。一旦当前函数超出范围,您就无法再访问参数的任何变量。

是用于动态分配的大型内存池。使用new运算符分配内存时,将从堆中分配此内存。在创建当前函数终止后不想丢失的对象时,您希望分配堆内存(丢失范围)。对象存储在堆中,直到使用deletefree()取消分配空间。

答案 4 :(得分:0)

考虑这个例子:

您实现了一个链表,该链表具有类节点的字段成员头。
每个节点都有一个字段成员next。如果Node类型的这个成员而不是Node *,那么每个Node的大小将取决于它在链中的节点数量。

例如,如果列表中有100个节点,那么您的头部成员将是巨大的。因为它将下一个节点保存在其自身内部,所以它需要有足够的大小来容纳它,然后保持下一个节点,依此类推。因此,头部必须有足够的空间容纳99个节点,接下来的98个等等......

你想避免这种情况,所以在这种情况下,指向每个节点中的下一个节点而不是下一个节点本身会更好。