std vector C++ - 深或浅副本

kir*_*off 47 c++ copy vector std deep-copy

我想知道是否复制一个向量我正在用它的值复制向量(而这不适用于数组,深度复制需要一个循环或memcpy).

你能暗示解释一下吗?

问候

And*_*rew 85

复制矢量时,您正在制作深层复制.但是如果你的向量是一个指针向量,你得到的是指针的副本,而不是指向的值

例如:

std::vector<Foo> f;
std::vector<Foo> cp = f; //deep copy. All Foo copied

std::vector<Foo*> f;
std::vector<Foo*> cp = f; //deep copy (of pointers), or shallow copy (of objects).
//All pointers to Foo are copied, but not Foo themselves
Run Code Online (Sandbox Code Playgroud)

  • 混淆可能来自于"指针"和"指针"之间缺失的区别.指针只是普通的对象,它们的确被完全按照预期的方式复制.这是人们对此感到困惑的*pointees*. (5认同)
  • 有时候,当我看到这些术语在不同的帖子中被不同地使用时,我发现这些术语令人困惑.可以说,就指针而言,它们是浅色的; 两者似乎都是正确的,取决于你如何解释它们. (3认同)
  • +1我会认为第二个例子是浅拷贝.`int*a,*b; A = B; //浅拷贝.在矢量的情况下,我们不是这样做的吗?BTW,它的de*e*p而不是deap :) (2认同)
  • @user833771 问题与`unique_ptr` 无关。对于“unique_ptr”,它不能被复制,你可以“移动”它或创建一个新的深度复制内容。 (2认同)

Chr*_*een 6

矢量将调整大小以便为对象提供足够的空间。然后它将迭代对象并为每个对象调用默认的复制运算符。

这样,向量的副本就“深”了。向量中每个对象的副本是为默认复制运算符定义的任何内容。

在示例中......这是错误的代码:

#include <iostream>
#include <vector>

using namespace std;

class my_array{
public:
    int *array;
    int size;
    my_array(int size, int init_val):size(size){
        array = new int[size];
        for(int i=0; i<size; ++i)
            array[i]=init_val;
    }
    ~my_array(){
        cout<<"Destructed "<<array[0]<<endl;
        if(array != NULL)
            delete []array;
        array = NULL;
        size = 0;
    }

};

void add_to(vector<my_array> &container){
    container.push_back(my_array(4,1));
}

int main(){

    vector<my_array> c;
    {
        my_array a(5,0);
        c.push_back(a);
    }
    add_to(c);
    //At this point the destructor of c[0] and c[1] has been called.
    //However vector still holds their 'remains'
    cout<<c[0].size<<endl; //should be fine, as it copies over with the = operator
    cout<<c[0].array[0]<<endl;//undefined behavior, the pointer will get copied, but the data is not valid
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是更好的代码:

#include <iostream>
#include <vector>

using namespace std;

class my_array{
public:
    int *array;
    int size;
    my_array(int size, int init_val):size(size){
        cout<<"contsructed "<<init_val<<endl;
        array = new int[size];
        for(int i=0; i<size; ++i)
            array[i]=init_val;
    }
    my_array(const my_array &to_copy){
        cout<<"deep copied "<<to_copy.array[0]<<endl;
        array = new int[to_copy.size];
        size = to_copy.size;
        for(int i=0; i<to_copy.size; i++)
            array[i]=to_copy.array[i];
    }

    ~my_array(){
        cout<<"Destructed "<<array[0]<<endl;
        if(array != NULL)
            delete []array;
        array = NULL;
        size = 0;
    }

};

void add_to(vector<my_array> &container){
    container.push_back(my_array(4,1));
}

int main(){

    vector<my_array> c;
    {
        my_array a(5,0);
        c.push_back(a);
    }
    add_to(c);
    //At this point the destructor of c[0] and c[1] has been called.
    //However vector holds a deep copy'
    cout<<c[0].size<<endl; //This is FINE
    cout<<c[0].array[0]<<endl;//This is FINE
    return 0;
}
Run Code Online (Sandbox Code Playgroud)