将push_back()“new”作为一个对象添加到c ++

时间:2016-02-05 10:02:46

标签: c++ c++11 gcc stl

我是c ++标准库的新手。我想使用std :: list。我知道如果我自己创建一个列表而不是使用stl,我应该将内存分配给一个新对象,然后将其添加到列表中。

A类的c风格列表:

A *ptrA = new A();     
ptrA->setElement(value);
ptrA->next = null;
currentPositionMyCstyleList->next = ptrA;
ptrA->prev = currentPositionMyCstyleList;

如果我使用stl,是否需要“新”一个对象?将push_back()“new”作为对象添加到c ++中的std :: list之前?

下面的代码是否正确?

A aObj(value);     
listA.push_back(aObj); // Will push_back() "new" an object and copy the value of aObject to the object before add it to list

aObj的值是否会在下面的代码中发布:

funcAddToList() {
    A aObj(value);     
    listA.push_back(aObj);
}
funcDispList() {
    // display listA  // Does the value of aObj still in list?
}

push_back()实际上做了什么?

在阅读stl_list.h_push_back()_M_insert_M_create_node

后,我仍然感到困惑

感谢您的时间。

5 个答案:

答案 0 :(得分:2)

push_back中的std::list方法会复制或移动您的参数。

在内部,由实现来处理它想要管理对象的方式。

答案 1 :(得分:2)

很可能......

该列表有一个分配器。默认分配器只调用new(正如您所期望的那样)。 如果适合,您可以提供备用分配器。

由于你正在使用C ++ 11,你可能会从emplace_back中受益,这应该避免你所产生的任何构造/移动/释放开销。

emplace_back仍会调用分配器...

或者,如果你'移动'中的值,它可能会有所帮助:

list.push_back(std::move(v));

假设您已经在元素类型上定义了有用的移动语义。

答案 2 :(得分:1)

std::list可以包含对象或指向对象的指针。

std::list<MyObj> list1;
list.push_back(MyObj()); // push an anonymous object (rvalue)
MyObj a;
list.push_back(a); // push (copy) a

std::list<MyObj*> list2;
list2.push_back(new MyObj());
MyObj* b = new MyObj();
list2.push_back(b);

list1是MyObj的列表,当您清除列表时,列表中的MyObj实例将被销毁并释放内存。 list2是一个指针列表,当您清除列表时,实例不会被销毁。

push_back在堆上创建参数的副本。但list2是一个指针列表,因此只复制指针,而不是对象本身。

由于其临时行为,匿名对象(称为rvalue)可以被移动&#34;在列表中:内存未被分配,但列表中的指针将指向已分配的内存。此行为取决于push_back的类型和实现。

答案 3 :(得分:1)

是的,来自push_back的{​​{1}}使用std::list(或new)在堆上创建新对象。它创建了参数的副本。

你的第二个片段是正确的。 malloc()已被复制。

aObj的第三个代码段将保留在列表中,而aObj本身将被删除。

答案 4 :(得分:0)

如果容器的模板参数是POD类型,则push_back为其分配一个新的内存块,并使用传递的值进行初始化。如果template参数是复杂数据类型a-ka类的对象,那么它也会被分配,然后使用复制构造函数调用进行实例化(复制构造函数的参数将是push_back的传递参数)。