2012-07-05 67 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