替换对象向量的元素

Replacing element of a vector of objects

本文关键字:元素 向量 对象 替换      更新时间:2023-10-16

我有一std::vector对象。如何替换索引 i 处的元素,同时确保调用当前驻留在那里的对象的析构函数?我可以做:

std::vector<myClass> V;
V.push_back(getObj());
V[0] = getAnotherObj(); // Will the current V[0]'s destructor be called?

具体来说,如果我有一个向量向量会发生什么?

std::vector<std::vector<int>> V;
V.push_back(getARandomVector(10));
V[0] = getARandomVector(5); // Will the current V[0] vector be cleared or destroyed? If not, will I have a memory leak?

std::vector管理其拥有的对象的内存和生存期。它将它们保存为类型。

如果v是一个std::vector<T>,那么v[0] = x将产生类似的效果,就好像你在函数中T t;声明为局部变量,然后写t = x一样。 t不会被销毁,但将要发生的是将调用复制赋值运算符。当t超出范围时,将调用析构函数。

std::vector 将在对象被销毁或放大到必须分配新存储时调用对象的析构函数。然后它会将它们复制/移动到新存储中并销毁旧存储。

std::vector<myClass> V;
V.push_back(getObj());
V[0] = getAnotherObj(); // Will the current V[0]'s destructor be called?

如果您认为将调用析构函数,那么您可能希望复制构造函数将在它之后立即调用。然而,这不是它所期望的行为方式。有两个规则:

  1. 如果必须在复制发生之前创建新对象,则使用复制构造函数。

  2. 如果在复制之前不必创建新对象,则使用赋值运算符。

因此,预计不会调用析构函数。没有理由销毁该对象,然后再次创建另一个相同类型的对象。

编辑:

由于问题已经过编辑,现在有这部分:

std::vector<std::vector<int>> V;
V.push_back(getARandomVector(10));
V[0] = getARandomVector(5); // Will the current V[0] vector be cleared or destroyed? If not, will I have a memory leak?

据此

复制 (1( vector& operator= (const vector& x);

移动 (2( vector& operator= (vector&& x);

初始值设定项列表 (3( vector& operator= (initializer_list<value_type> il);

复制赋值 (1( 将所有元素从 x 复制到 容器(X 保留其内容(。

移动赋值 (2( 将 x 的元素移动到容器 (x 保持未指定但有效的状态(。

初始值设定项列表赋值 (3( 将 il 的元素复制到 容器。

容器保留其当前分配器,除非分配器 特征表明 X 的分配器应该传播。此分配器是 用于(通过其特征(分配和释放存储,如果 发生重新分配,并在需要时构建或销毁元素。

调用之前容器中保存的任何元素都被分配到或销毁。

为了确保销毁和重建,您可以使用放置 new 和删除:

V[0].~myClass();
new(&V[0]) myClass(getAnotherObj());

然而,这可能是一个坏主意。 V[0] = getAnotherObj();产生相同的最终结果,并且要简单得多。