2012-07-05 113 views
31

不知是否复制载体,我与它的值复制向量(而这是不具有阵列工作,并深拷贝需要一个循环或memcpy的)。矢量STD C++ - 深或浅拷贝

你能暗示一个解释吗?

问候

+0

不要使用'memcpy'为'VECTOR'。 vector中包含的对象可能不是POD,它们可能是具有虚函数的类。使用'std :: copy'或简单的'vector '来指定'vector '作业。 – Ajay 2012-07-05 16:57:01

+2

“深”与“浅”的区别在默认值语义的语言中没有多大意义,并且不试图隐藏它使用指针的事实(以便指针是具有自己的值的对象,从他们参考的对象)。副本将始终是按值,并且这是否构成“深层”复制与“浅层”复制取决于您的定义。 – bames53 2012-07-05 18:00:42

回答

62

你正在一个深拷贝复制的向量的任何时间。但是,如果你的载体是你所得到的指针的副本指针的载体,而不是值指出

例如:

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 
+2

+1我会认为第二个例子是浅拷贝。 'int * a,* b; A = B; //浅复制'。在矢量的情况下,我们是不是在做这样的事情?顺便说一下,它的de * e * p和不是deap :) – Mahesh 2012-07-05 16:16:04

+3

有时我发现这些术语混淆,当我看到他们在不同的职位使用不同的方式。人们可以说,在指针的情况下,它们是浅拷贝;两者似乎都是正确的,这取决于你如何解释它们。 – Nawaz 2012-07-05 16:16:35

+5

混淆可能来自“指针”和“指尖”之间的缺失区分。指针只是普通的对象,它们的确按照人们期望的方式复制。这是人们困惑的* pointees *。 – 2012-07-05 17:13:04

1

向量将调整到有物体足够的空间。然后它将遍历这些对象并为每个对象调用默认的复制操作符。

以这种方式,向量的副本是'深'。矢量中每个对象的副本是为默认的复制操作员定义的。

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

#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; 
} 

这是更好的代码:

#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; 
} 
+0

更好的是,仍然是五大规则。 :)(你使用了较旧的三条规则) – Arafangion 2017-08-04 00:51:42