这些用法有什么区别:new SubElement()和SubElement()?

时间:2010-04-02 15:49:13

标签: c++ memory new-operator

在类构造函数中,我需要动态创建一些对象并将它们添加到向量中。这是我的代码:

ContainerClass::ContainerClass() {
   for (int i = 0; i < limit; i++)
      elements.push_back(SubElement());
}

这与新的SubElement()是一回事吗?我是否仍需要将这些SubElement()对象释放到ContainerClass析构函数中?

4 个答案:

答案 0 :(得分:6)

方法1:

如果您有std::vector<SubElement> elements;
然后你会使用elements.push_back(SubElement())

SubElement()在堆栈上创建SubElement,然后将副本添加到vector

您不应在delete的各个元素上调用vector。当vector超出范围时,它们将被破坏并解除分配。

方法2:

如果您有std::vector<SubElement*> elements;
然后你会使用elements.push_back(new SubElement())

new SubElement()在堆上创建SubElement,然后该元素的地址存储在vector中。

delete超出范围之前,您需要在各个元素上调用vector,否则您将创建内存泄漏。只有在每个元素上调用delete时,它们才会被破坏和解除分配。

答案 1 :(得分:1)

SubElement():自动分配,新的SubElement():动态分配。

经验法则:您不需要删除未使用new创建的对象。

答案 2 :(得分:1)

不 - 他们是不同的。

只需SubElement()创建一个自动(堆栈)对象,应该将其复制以便保存。

new SubElement()在堆上创建一个动态分配的对象,并应分配给指向此类对象的指针。它必须最终释放,以防止内存泄漏。

答案 3 :(得分:1)

这不是一回事。在大多数面向对象的语言中,特别是具有任何类型的内置垃圾收集的语言,所有对象都在堆上分配,变量总是包含指向对象的指针,而不是对象本身。

C ++是少数面向对象语言之一,您可以通过值引用对象。

new的情况下,您正在创建一个对象并被赋予指向它的指针。然后,您将通过指针而不是直接引用对象。在另一种情况下,您正在堆栈上创建对象,容器将存储自己的副本。

通常,基于堆栈的副本将通过引用引用(&背后的整个概念作为类型限定符),但这些引用通常被理解为短暂的并且通常由该事物组成。如果该东西需要存储一段时间,则被引用。

特别是在这种情况下,如果你有一个指针容器(即::std::vector<SubElement *> c),它会存储指向对象的指针,你通常会用new分配它们。但是标准库容器类(以及大多数其他容器类)不会为您删除指针。他们不接受指针的'所有权'。因此,您将自行负责删除它们。

如果您有一个对象容器(即::std::vector<SubElement> c),那么您将使用c.push_back(SubElement())表单,容器将存储您正在创建的临时对象的副本。容器确实拥有这些副本的所有权,并且还经常在内部复制它们。这就是为什么按值存储在容器中的对象需要实现复制构造函数。

有一种方法可以让容器获取指针的所有权,但只是间接地。您可以让容器存储自己拥有所有权的对象的副本。人们使用的标准类是::std::tr1::shared_ptr<T>。您的容器声明如下:::std::vector< ::std::tr1::shared_ptr<SubElement> > c。然后,您可以执行:c.push_back(new SubElement());,容器将在完成后删除SubElement对象。

您应该阅读shared_ptr,并在使用之前了解它的作用。