类成员在堆上还是栈上分配?

9
如果一个类被声明如下:
class MyClass
{
  char * MyMember;
  MyClass()
  {
    MyMember = new char[250];
  }
  ~MyClass()
  {
    delete[] MyMember;
  }
};

这可以这样完成:
class MyClass
{
  char MyMember[250];
};

一个类如何在堆上分配,比如我执行MyClass * Mine = new MyClass(); 分配的内存是否也会分配第二个示例中的250字节,以及成员变量是否在MyClass对象的整个生命周期内有效? 至于第一个示例,将类成员分配到堆上是否可行?


可能是 类成员和显式堆栈分配 的重复问题。 - underscore_d
3个回答

7

是的,是的,还是的。

然而,您第一个示例中存在一些错误:因为其中一个数据成员是具有堆分配数据的指针,所以它还应该声明一个复制构造函数和赋值运算符,例如像这样...

MyClass(const MyClass& rhs) 
{
  MyMember = new char[250]; 
  memcpy(MyMember, rhs.MyMember, 250);
}

谢谢你的建议,我会考虑更经常地使用这种技术。 - SimpleButPerfect
3
尽管 Chris 在技术上是正确的,但这样做并不是一个好主意。相反,使用 std::vector<char> 会更好,它会自动处理你所有的内存管理。要了解完整细节,请查看此链接:https://dev59.com/BnVC5IYBdhLWcg3wjx5d#255744。 - Martin York
1
这个问题根本不是关于数组的,我应该改变这个例子,它是关于分配概念本身的。 - SimpleButPerfect

3

注意:请使用std :: string代替堆分配的char []。

在第二个示例中,分配的内存是否也分配了250字节以及类实例化?

它将在构造函数中进行堆分配,就像在堆栈分配的MyClass中一样。这取决于你所说的“一起”,它不一定会被一起分配。

成员变量是否在MyClass对象的整个生命周期内有效?

是的。

至于第一个示例,将类成员分配在堆上是否可行?

是的,在某些情况下。有时您想要最小化头文件中的包含,并且有时您将使用工厂函数来创建成员。但通常,我只选择简单的非指针成员。


非常感谢您提供如此详细的答案,至于早期的笔记,我只是在尝试收集有关该主题的知识。 - SimpleButPerfect

1

当你调用new时,它会从堆中分配内存,否则它会从栈中分配内存(我们将忽略malloc及其类似物)。

在你的第一个示例中,两者都会分配空间:在栈上为MyClass实例分配4个字节(假设32位指针),在堆上为MyMember分配250个字节的缓冲区。

在第二个示例中,将在栈上为MyClass实例分配250个字节。在这种情况下,MyMember被视为实例的偏移量。


1
这并不是完全正确的,第二个例子中,类包含了一个250个字符的数组。如果你像这样做MyClass *foo = new MyClass;,那么所有都将在堆上。 - Hasturkun
啊 - 我没有看到 new MyClass (或者也许是 OP 在“编辑不会被记录”的时间范围内添加的)。所以,就目前问题而言,这个答案完全不正确。但不幸的是,我无法删除它。 - Anon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接