2012-07-05 25 views
31

मुझे आश्चर्य है कि एक वेक्टर की प्रतिलिपि बना रहा हूं, मैं वेक्टर को इसके मूल्यों के साथ प्रतिलिपि बना रहा हूं (जबकि यह सरणी के साथ काम नहीं कर रहा है, और गहरी प्रतिलिपि को लूप या memcpy की आवश्यकता है)।std वेक्टर सी ++ - गहरी या उथली प्रतिलिपि

क्या आप एक स्पष्टीकरण के संकेत दे सकते हैं?

सादर

+0

'vector' के लिए memcpy' का प्रयोग न करें'

उदाहरणों में ... यह बुरा कोड है। वेक्टर में निहित वस्तु पीओडी नहीं हो सकती है, वे वर्चुअल फ़ंक्शन वाले वर्ग हो सकते हैं। 'Std :: copy' या सरल' वेक्टर ''वेक्टर ' असाइनमेंट का उपयोग करें। – Ajay

+2

'गहरी' बनाम 'उथला' भेद एक ऐसी भाषा में अधिक समझ में नहीं आता है जो मूल्य अर्थशास्त्र के लिए डिफ़ॉल्ट है और इस तथ्य को छिपाने की कोशिश नहीं करता है कि यह पॉइंटर्स का उपयोग करता है (ताकि पॉइंटर्स अपने मूल्यों के साथ ऑब्जेक्ट्स हों वे ऑब्जेक्ट से संदर्भित करते हैं)। प्रतियां हमेशा मूल्यवान होंगी, और क्या यह 'गहरी' प्रतिलिपि बनाम 'उथले' प्रतिलिपि बनाने की आपकी परिभाषा पर निर्भर करती है। – bames53

उत्तर

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; // शालो कॉपी'। वैक्टरों के मामले में, क्या हम ऐसा कुछ नहीं कर रहे हैं? बीटीडब्लू, इसकी डी * ई * पी और डेप नहीं है :) – Mahesh

+3

कभी-कभी मुझे इन शब्दावली को भ्रमित करने लगता है जब मैं उन्हें विभिन्न पदों में अलग-अलग इस्तेमाल करता हूं। कोई कह सकता है, पॉइंटर्स के मामले में, वे उथले-प्रतिलिपि हैं; दोनों सही तरीके से प्रतीत होते हैं, इस पर निर्भर करते हुए कि आप उन्हें कैसे समझते हैं। – Nawaz

+5

भ्रम शायद "पॉइंटर्स" और "पॉइंट्स" के बीच एक लापता भेद से आता है। पॉइंटर्स केवल सामान्य वस्तुएं हैं, और वास्तव में वे वास्तव में जिस तरह से उम्मीद करेंगे उसकी प्रतिलिपि बनाई जाती हैं। यह * पॉइंट्स * है कि लोग उलझन में हैं। –

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

संबंधित मुद्दे