C++ vector push_back

use*_*879 21 c++ vector

将新对象元素推送到std::vector?的正确方法是什么?我希望数据在向量中分配.这会将对象复制newradio到向量中,然后newradio在超出范围时(例如在堆栈外)摆脱它吗?

vector<Radio> m_radios;
Radio newradio(radioNum);
m_radios.push_back(newradio);
Run Code Online (Sandbox Code Playgroud)

然后当我释放包含的对象时m_radios,这将释放向量分配的所有内存吗?

Eti*_*tel 38

std::vector管理自己的记忆.这意味着,当调用向量的析构函数时,向量所占用的内存将被释放.std::vector还调用时,它被移除对象的析构函数(通过erase,pop_back,clear或载体的析构函数).

当你这样做:

Radio newradio(radioNum);
m_radios.push_back(newradio);
Run Code Online (Sandbox Code Playgroud)

您将newradio(使用Radio's复制构造函数创建)的副本添加到向量.newradio当它超出范围时将被销毁,并且当从向量中移除副本时(例如任何对象),副本将被销毁.

这是一个重点:std::vector只存储一个对象的副本,这意味着该对象必须有一个有意义的复制构造函数(和赋值运算符,但这是另一个问题).如果你有一个指针向量,那么指针本身将被复制,而不是指向它.请注意,对于每个标准容器(如std::liststd::set),此行为都是相同的.

根据经验,如果你没有使用指针,那么你不必担心自己释放内存.

在C++ 11中,大多数标准容器(包括vector)都有一个emplace_back方法,可以在容器的末尾构建一个对象.它需要一堆参数并调用最能匹配这些参数的构造函数(如果不存在这样的构造函数,则会失败),使用所述构造函数在容器的末尾创建没有任何副本的对象.因此,上面的代码可以重写为:

m_radios.emplace_back(radioNum); // construct a Radio in place, 
                                 // passing radioNum as the constructor argument
Run Code Online (Sandbox Code Playgroud)

同样在C++ 11中,容器通常可以移动,因此它们不再需要对象可复制:如果它们是可移动的,则容器将根据需要移动其内容(例如在重新分配期间).如果要复制矢量,仍然需要可复制类型.

  • 虽然当时是正确的,但这个答案可能会使用提及`emplace_back`的更新 (5认同)