【问题标题】:Are these created on the heap or stack [duplicate]这些是在堆还是堆栈上创建的[重复]
【发布时间】:2013-12-09 13:16:14
【问题描述】:

说我有这样的课程

class foo
{
  private:
  std::string str;
  int a;
  poo* p;

  public:
  foo
  {
     p = new poo();
  }

  void someMethod() {....}
}

现在我想知道我是否走以下路:

foo* f = new foo();

或

foo f;

变量str、a 和p 在每种情况下会在哪里创建?成员变量是否受类创建方式的影响?例如,我认为str 和a 将在堆栈上创建,p 将在堆上创建。如果有人能解决这个问题,我将不胜感激..

【问题讨论】:

  • 我理解那部分。在堆或栈上创建会影响内部成员变量
  • @MistyD 是的。
  • 不要将指针 p 与其指向的 poo 对象混淆。前者是foo 对象的一部分,后者始终是单独的堆分配。
  • 想象一下如果将成员放入堆栈然后函数返回会发生什么。

标签: c++


【解决方案1】:

poo 实例 p 指向的始终位于堆上,但指针本身 (p) 位于 foo 实例中/处。

在第一个版本 (foo* f = new foo()) 中,在堆上创建了一个 foo 实例(包括它的所有成员,它们总是在同一个地方),指向它的指针(f var)是存储在堆栈或某个寄存器中(这取决于编译器)。

在第二个版本中,foo 实例位于堆栈上(包括其所有成员)。

但请注意,对象的实际位置并不像对象的实际范围那么重要。你真的应该查一下 RAII 这个词。

【讨论】:

  • 您说 foo* f = new foo() 在堆上创建 foo。我同意这一点,但你说str 和a 也分配在堆上。我很难理解这一点。因为当我们删除 f 的实例时,str 和 a 被删除(超出范围)。如果它们在堆上,我们不必手动删除它们
  • str 和 a 位于 foo 所在的位置,在这种情况下位于堆上。如果你有一个对象,它的所有成员都按顺序排列,从上到下。所以首先是str,然后是a,然后是p(注意,指针p,x86 上的一个32 位整数)。 f 指向我们称之为对象或实例的这个组的开始;)。如果实例本身离开范围,它们只会“超出范围”(在处理堆分配的实例时谈论范围有点令人困惑)。如果您执行delete f;,就会出现这种情况。从技术上讲,析构函数将分别调用它们的析构函数。
  • 这里想补充一点关于继承的东西。如果您有一个关系class Child : public Parent,那么Parents 的所有成员都在顶部,而在它们之下的是Child 的成员,就像它们是两个单独的对象一样。这也意味着如果将this 指针作为this 指针传递给Child(基本上是basePtr + [size of Parent])的方法,则必须在技术上“强制转换”Child* 指针。如果Parent有一些虚方法,则在开头放置一个vftable,如果Child有一些虚方法,则在“子部分”开头放置一个vftable。
【解决方案2】:

类的非静态数据成员在创建类对象的地方创建。

【讨论】:

  • @rightfold 感谢更新。:)
猜你喜欢
  • 2012-07-29
  • 2011-02-03
  • 2016-12-27
  • 2010-11-06
  • 1970-01-01
  • 2019-12-02
  • 2011-04-08
  • 2016-03-06
  • 2013-10-26
相关资源
最近更新 更多