我是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
后,我仍然感到困惑感谢您的时间。
答案 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
的传递参数)。