替换对象矢量的元素

时间:2015-09-03 03:23:06

标签: c++ vector

我有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?

3 个答案:

答案 0 :(得分:3)

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

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

std::vector 在对象被销毁时调用它们的析构函数,或者当它变得足够大以至于必须分配新存储时。然后它会将它们复制/移动到新存储中并销毁旧存储。

答案 1 :(得分:2)

std::vector<myClass> V;

V.push_back(getObj());
V[0] = getAnotherObj(); // Will the current V[0]'s destructor be called?

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

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

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

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

    编辑:

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

    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?
    

    根据this

      

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

         

    move(2)vector& operator= (vector&& x);

         

    初始化列表(3)vector& operator= (initializer_list<value_type> il);

         

    复制分配(1)将x中的所有元素复制到   容器(x保留其内容)。

         

    移动赋值(2)将x的元素移动到容器中(x   留在未指定但有效的状态。)

         

    初始化列表赋值(3)将il的元素复制到   容器

         

    除了分配器之外,容器保留其当前分配器   特征表明x的分配器应该传播。这个分配器是   如果使用(通过其特征)来分配和释放存储   如果需要,重新分配,并构造或销毁元素。

         

    在分配之前,容器中保留的所有元素都已分配    to或destroy。

答案 2 :(得分:2)

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

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

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