गहरी प्रति और उथली प्रति के बीच क्या अंतर है?


754

गहरी प्रति और उथली प्रति के बीच क्या अंतर है?


6
यह किस तकनीक के तहत आता है?
सुरेश वर्मा

42
@ सुरेशवर्मा, यह एक प्रोग्रामिंग अवधारणा है!
मनीष श्रीवास्तव

जवाबों:


759

उथले नकल के रूप में संभव के रूप में थोड़ा नकल। संग्रह की उथली प्रतिलिपि संग्रह संरचना की एक प्रति है, तत्वों की नहीं। उथली प्रतिलिपि के साथ, दो संग्रह अब व्यक्तिगत तत्वों को साझा करते हैं।

गहरी नकलें सब कुछ नकल करती हैं। एक संग्रह की एक गहरी प्रतिलिपि दो संग्रह है जिसमें मूल संग्रह के सभी तत्वों को दोहराया गया है।


हो सकता है। .NET मेम्बरवाइकल () कार्यान्वयन पारंपरिक अर्थों में उथले नकल से अधिक है
Lu55

5
ध्यान रखें कि मिश्रित प्रतियाँ भी हैं (न केवल आलसी प्रतिलिपि के रूप में ), जो इसके केवल भाग की नकल करती है ( यहाँ एक उदाहरण है )! ;)
क्रेगॉक्स

तो X की उथली प्रतिलिपि X में तत्वों को बदल सकती है लेकिन एक गहरी प्रतिलिपि नहीं बना सकती है?
सज़ा

1
संग्रह संरचना क्या है?
हनी

1
@ हनी कलेक्शंस विविध डेटा स्ट्रक्चर्स हो सकते हैं जो कई डेटा आइटम्स को स्टोर करते हैं। अजगर में हम
मर्फी

850

चौड़ाई बनाम गहराई; जड़ नोड के रूप में अपनी वस्तु के साथ संदर्भ के एक पेड़ के संदर्भ में सोचो।

उथला:

कॉपी करने से पहले उथला नकल उथला हो गया

चर ए और बी स्मृति के विभिन्न क्षेत्रों को संदर्भित करते हैं, जब बी को ए को सौंपा जाता है दो चर स्मृति के एक ही क्षेत्र को संदर्भित करते हैं। बाद में या तो सामग्री में संशोधन दूसरे की सामग्री में तुरंत परिलक्षित होता है, क्योंकि वे सामग्री साझा करते हैं।

दीप:

कॉपी करने से पहले गहरी नकल दीप किया

चर A और B स्मृति के विभिन्न क्षेत्रों को संदर्भित करते हैं, जब B को A स्मृति क्षेत्र में उन मानों को सौंपा जाता है जिन्हें A बिंदुओं में स्मृति क्षेत्र में कॉपी किया जाता है। बाद में या तो ए या बी के लिए अद्वितीय सामग्री में संशोधन; सामग्री साझा नहीं कर रहे हैं।


32
यहाँ विकिपीडिया लेख है कि इस उदाहरण के मामले में से आता है यह आप के लिए संदर्भ से बाहर मतलब नहीं है है en.wikipedia.org/wiki/Object_copy#Shallow_copy
कोर्बिन

4
उथले कॉपी के मामले में अगर हम सरणी B में कोई बदलाव करते हैं तो क्या A और B दोनों ए स्मरण स्थान की ओर इंगित करते हुए ए में दिखाई देंगे?
टेक

3
एकल पंक्ति में इसकी कॉपी संदर्भ बनाम कॉपी मूल्य द्वारा। उत्तर सही है तो निश्चित नहीं!
मन्नू

2
छवियाँ सीधे प्रशस्ति के बिना विकिपीडिया से ली गई
jasonleonhard

9
@ajonleonhard तो 9 साल पहले मैं सिर्फ छवियों के लिए यूआरएल डाल दिया क्योंकि एम्बेडिंग छवियों का समर्थन नहीं किया गया था। इस प्रकार URL ने अपने स्रोत का हवाला दिया। समुदाय ने बाद में उस पर किसी प्रकार का उद्धरण संपादित किए बिना URL को एम्बेडेड छवियों में बनाया। 4 साल की शीर्ष टिप्पणी भी इंगित करती है कि आप क्या इंगित करते हैं। एक नज़र है: stackoverflow.com/posts/184780/revisions क्यों न केवल अपने आप को जवाब में एक उद्धरण संपादित करें? अगली बार जब कोई मेरी 10 साल पुरानी लेखन शैली के बारे में कोई शिकायत करे तो मैं अनुपलब्ध हो सकता हूं।
dlamblin

156

संक्षेप में, यह इस बात पर निर्भर करता है कि कौन से बिंदु क्या हैं। उथली प्रतिलिपि में, ऑब्जेक्ट B स्मृति में ऑब्जेक्ट A के स्थान को इंगित करता है। डीप कॉपी में ऑब्जेक्ट ए की मेमोरी लोकेशन में सभी चीजें ऑब्जेक्ट बी की मेमोरी लोकेशन पर कॉपी हो जाती हैं।

इस विकी लेख में एक महान आरेख है।

http://en.wikipedia.org/wiki/Object_copy


112

निम्नलिखित छवि पर विचार करने का प्रयास करें

यहां छवि विवरण दर्ज करें

उदाहरण के लिए Object.MemberwiseClone एक उथली प्रतिलिपि लिंक बनाता है

और ICloneable इंटरफ़ेस का उपयोग करके आप यहां बताए अनुसार गहरी प्रतिलिपि प्राप्त कर सकते हैं


28
एक तस्वीर एक हजार शब्दों के बराबर होती है।
लेवी फुलर

6
अरे लड़का, यहाँ अर्थ खोजने के लिए आया था। यह एकमात्र उत्तर है जिसने मदद की।
करण सिंह

1
यह सबसे सरल और अभी तक केवल वही दिखाता है जो आवश्यक है।
हिना १०३१३

1
सबसे अच्छा चित्रण
मुहम्मद नायब

69

विशेष रूप से iOS डेवलपर्स के लिए:

यदि Bएक उथली प्रतिलिपि है A, तो आदिम डेटा के लिए यह पसंद है B = [A assign];और वस्तुओं के लिए यह पसंद है B = [A retain];

B और A एक ही मेमोरी लोकेशन की ओर इशारा करते हैं

अगर Bकी एक गहरी प्रतिलिपि है A, तो यह पसंद हैB = [A copy];

B और A अलग-अलग मेमोरी लोकेशन की ओर इशारा करते हैं

B मेमोरी एड्रेस A के समान है

B में A की समान सामग्री है


8
"B मेमोरी एड्रेस A के समान है" - कैसे आए?

2
डीप कॉपी में, "B मेमोरी एड्रेस A के समान नहीं है"
ismail baig

60

उथली प्रतिलिपि: सदस्य मानों को एक वस्तु से दूसरी वस्तु में कॉपी करता है।

डीप कॉपी: सदस्य मान को एक ऑब्जेक्ट से दूसरे ऑब्जेक्ट में कॉपी करता है।
                     कोई भी पॉइंटर ऑब्जेक्ट डुप्लिकेट और डीप कॉपिड हैं।

उदाहरण:

class String
{
     int   size;
     char* data;
};

String  s1("Ace");   // s1.size = 3 s1.data=0x0000F000

String  s2 = shallowCopy(s1);
 // s2.size =3 s2.data = 0X0000F000
String  s3 = deepCopy(s1);
 // s3.size =3 s3.data = 0x0000F00F
 //                      (With Ace copied to this location.)

47

मैंने यहाँ उत्तर को समझने के लिए छोटा, आसान नहीं देखा है - इसलिए मैं इसे आज़माऊँगा।

उथली प्रतिलिपि के साथ, स्रोत द्वारा इंगित की गई कोई भी वस्तु भी गंतव्य द्वारा इंगित की जाती है (ताकि कोई संदर्भित वस्तुओं की नकल न हो)।

एक गहरी प्रतिलिपि के साथ, स्रोत द्वारा इंगित की गई किसी भी वस्तु को कॉपी किया जाता है और प्रतिलिपि गंतव्य द्वारा इंगित की जाती है (इसलिए अब प्रत्येक संदर्भित ऑब्जेक्ट में से 2 होंगे)। यह वस्तु के पेड़ को गिरा देता है।



36

{दो वस्तुओं की कल्पना करें: A और B एक ही प्रकार _t (C ++ के संबंध में) और आप उथले / गहरी नकल के बारे में सोच रहे हैं A से B}

उथला प्रतिलिपि: बस ए में संदर्भ की एक प्रति बी में बनाता है। ए के पते की एक प्रति के रूप में इसके बारे में सोचो। तो, A और B के पते एक ही होंगे यानी वे एक ही मेमोरी लोकेशन यानी डेटा सामग्री की ओर इशारा करेंगे।

डीप कॉपी: बस ए के सभी सदस्यों की एक प्रति बनाता है, बी के लिए एक अलग स्थान में मेमोरी आवंटित करता है और फिर कॉपी किए हुए सदस्यों को गहरी कॉपी प्राप्त करने के लिए बी को असाइन करता है। इस तरह, यदि A अस्तित्वहीन B हो जाता है, तब भी स्मृति में मान्य है। उपयोग करने के लिए सही शब्द क्लोनिंग होगा, जहां आप जानते हैं कि वे दोनों पूरी तरह से समान हैं, लेकिन अभी तक अलग हैं (यानी मेमोरी स्पेस में दो अलग-अलग संस्थाओं के रूप में संग्रहीत)। आप अपना क्लोन आवरण भी प्रदान कर सकते हैं, जहाँ आप समावेश / बहिष्करण सूची के माध्यम से तय कर सकते हैं कि कौन से गुण गहरी प्रतिलिपि के दौरान चुने जाने हैं। जब आप एपीआई बनाते हैं तो यह काफी आम बात है।

आप शामिल होने वाले दांव को समझने के लिए केवल एक Shallow Copy ON__IF करना चुन सकते हैं । जब आपके पास C ++ या C से निपटने के लिए बड़ी संख्या में पॉइंटर्स होते हैं, तो किसी ऑब्जेक्ट की उथली प्रतिलिपि बनाना वास्तव में एक बुरा विचार है।

EXAMPLE_OF_DEEP COPY_ एक उदाहरण है, जब आप छवि प्रसंस्करण और ऑब्जेक्ट पहचान करने की कोशिश कर रहे हैं, तो आपको अपने प्रसंस्करण क्षेत्रों से " इर्रेलेवेंट एंड रिपिटिटिव मोशन" को मास्क करना होगा। यदि आप छवि बिंदुओं का उपयोग कर रहे हैं, तो आपके पास उन मुखौटा चित्रों को सहेजने के लिए विनिर्देश हो सकते हैं। अब ... यदि आप छवि की उथली प्रतिलिपि करते हैं, जब पॉइंटर संदर्भ स्टैक से हटाए जाते हैं, तो आप संदर्भ और इसकी प्रतिलिपि खो देते हैं अर्थात कुछ बिंदु पर पहुंच उल्लंघन की रनटाइम त्रुटि होगी। इस मामले में, आपको जो कुछ भी चाहिए वह आपकी छवि की एक गहरी प्रतिलिपि है, इसे CLONING करके। इस तरह आप भविष्य में उनकी जरूरत पड़ने पर मास्क को पुनः प्राप्त कर सकते हैं।

EXAMPLE_OF_SHALLOW_COPY मैं StackOverflow में उपयोगकर्ताओं की तुलना में बहुत जानकार नहीं हूँ इसलिए इस भाग को हटाने के लिए स्वतंत्र महसूस करें और यदि आप स्पष्ट कर सकते हैं तो एक अच्छा उदाहरण रखें। लेकिन मुझे वास्तव में लगता है कि उथली नकल करना एक अच्छा विचार नहीं है यदि आप जानते हैं कि आपका कार्यक्रम अनंत काल तक चलने वाला है या फ़ंक्शन कॉल के साथ स्टैक पर लगातार "पुश-पॉप" ऑपरेशन। यदि आप किसी शौकिया या नौसिखिए व्यक्ति (जैसे C / C ++ ट्यूटोरियल सामान) के लिए कुछ प्रदर्शित कर रहे हैं तो यह ठीक है। लेकिन अगर आप निगरानी और पहचान प्रणाली, या सोनार ट्रैकिंग सिस्टम जैसे कोई एप्लिकेशन चला रहे हैं, तो आप उथले को अपनी वस्तुओं की नकल करते हुए रखने वाले नहीं हैं क्योंकि यह आपके प्रोग्राम को जल्दी या बाद में मार देगा।


32
char * Source = "Hello, world.";

char * ShallowCopy = Source;    

char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);        

'ShallowCopy' स्मृति में उसी स्थान की ओर इंगित करता है जैसा 'स्रोत' करता है। 'डीपकोपी' स्मृति में एक अलग स्थान पर इंगित करता है, लेकिन सामग्री समान हैं।


22

शॉल कॉपी क्या है?

उथला प्रति एक वस्तु की एक बिट-वार प्रति है। एक नई ऑब्जेक्ट बनाई जाती है जिसमें मूल ऑब्जेक्ट में मानों की एक सटीक प्रतिलिपि होती है। यदि ऑब्जेक्ट का कोई भी फ़ील्ड अन्य ऑब्जेक्ट्स के संदर्भ हैं, तो केवल संदर्भ पते कॉपी किए गए हैं, यानी केवल मेमोरी एड्रेस कॉपी किया गया है।उथली प्रतिलिपि

इस आकृति में, प्रकार के MainObject1क्षेत्र field1int के हैं, और ContainObject1प्रकार के ContainObject। जब आप की एक उथली प्रतिलिपि करते हैं MainObject1, की प्रतिलिपि बनाई गई मान युक्त और अभी भी खुद को इंगित करने MainObject2के साथ बनाई field2गई है। ध्यान दें कि चूंकि यह आदिम प्रकार का है, इसलिए इसके मूल्य की नकल की जाती है , क्योंकि यह एक वस्तु है, फिर भी इंगित करता है । में किए गए बदलाव तो में में परिलक्षित होगा ।field1ContainObject1field1field2ContainedObject1MainObject2ContainObject1ContainObject1MainObject1MainObject2

अब अगर यह उथली प्रति है, तो देखते हैं कि गहरी प्रति क्या है?

डीप कॉपी क्या है?

एक गहरी प्रतिलिपि सभी क्षेत्रों को कॉपी करती है, और खेतों द्वारा इंगित गतिशील रूप से आवंटित स्मृति की प्रतियां बनाती है। एक गहरी प्रतिलिपि तब होती है जब किसी ऑब्जेक्ट को वस्तुओं के साथ कॉपी किया जाता है, जिसमें यह संदर्भित होता है। गहरी प्रति

इस चित्र में, MainObject1 क्षेत्रों के field1प्रकार int की, और ContainObject1के प्रकार के ContainObject। आप की एक गहरी प्रतिलिपि करते हैं MainObject1, MainObject2के साथ बनाई गई है field2की प्रतिलिपि बनाई मूल्य युक्त field1और ContainObject2की प्रतिलिपि बनाई मूल्य युक्त ContainObject1। में किए गए बदलाव नोट ContainObject1में MainObject1में दिखाई नहीं देगा MainObject2

अच्छा लेख


यह आपकी गलती नहीं है, हालांकि यह उदाहरण एक को संदर्भित करता है field3, जब उस मुद्दे के रूप में कुछ करने की कोशिश करने और समझने की स्थिति में होता है, उस उदाहरण में # 3 कहां हो रहा है ContainObject2 ?
Robb_2015 22

16

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में, एक प्रकार में सदस्य फ़ील्ड्स का संग्रह शामिल है। इन फ़ील्ड्स को या तो मान या संदर्भ द्वारा संग्रहीत किया जा सकता है (अर्थात, मान के लिए एक संकेतक)।

उथली प्रतिलिपि में, प्रकार का एक नया उदाहरण बनाया जाता है और मूल्यों को नए उदाहरण में कॉपी किया जाता है। संदर्भ बिंदु भी मानों की तरह ही कॉपी किए जाते हैं। इसलिए, संदर्भ मूल वस्तुओं की ओर इशारा कर रहे हैं। संदर्भ द्वारा संग्रहीत सदस्यों में कोई भी परिवर्तन मूल और प्रतिलिपि दोनों में दिखाई देते हैं, क्योंकि कोई भी प्रतिलिपि संदर्भित ऑब्जेक्ट से नहीं बनाई गई थी।

एक गहरी प्रतिलिपि में, मूल्य द्वारा संग्रहीत फ़ील्ड पहले की तरह कॉपी किए जाते हैं, लेकिन संदर्भ द्वारा संग्रहीत ऑब्जेक्ट के लिए पॉइंटर्स कॉपी नहीं किए जाते हैं। इसके बजाय, एक गहरी प्रतिलिपि संदर्भित ऑब्जेक्ट से बना है, और नई ऑब्जेक्ट के लिए एक पॉइंटर संग्रहीत है। उन संदर्भित वस्तुओं में किए गए कोई भी परिवर्तन ऑब्जेक्ट की अन्य प्रतियों को प्रभावित नहीं करेंगे।


12

'ShallowCopy' स्मृति में उसी स्थान की ओर इंगित करता है जैसा 'स्रोत' करता है। 'डीपकोपी' स्मृति में एक अलग स्थान पर इंगित करता है, लेकिन सामग्री समान हैं।


यह थोड़ा भ्रामक है। एक उथली और गहरी प्रति दोनों वस्तु को स्मृति में एक नए स्थान पर कॉपी कर देंगे, एक गहरी भी बच्चे की वस्तुओं की नकल करेंगे जबकि एक उथले में नए ऑब्जेक्ट्स पुराने बच्चों को संदर्भित करेंगे। मूल वस्तु का जिक्र किए बिना पढ़ना मुश्किल है।
बिल के

10

उथला क्लोनिंग:
परिभाषा: "किसी वस्तु की उथली प्रतिलिपि 'मुख्य' ऑब्जेक्ट की प्रतिलिपि बनाती है, लेकिन आंतरिक वस्तुओं की प्रतिलिपि नहीं बनाती है।" जब एक कस्टम ऑब्जेक्ट (उदाहरण। कर्मचारी) में सिर्फ आदिम, स्ट्रिंग प्रकार चर होते हैं, तो आप Shallow क्लोनिंग का उपयोग करते हैं।

Employee e = new Employee(2, "john cena");
Employee e2=e.clone();

आप super.clone();ओवरराइड किए गए क्लोन () विधि में वापस आते हैं और आपकी नौकरी खत्म हो जाती है।

डीप क्लोनिंग :
परिभाषा: "उथली प्रति के विपरीत, एक गहरी प्रति एक वस्तु की पूरी तरह से स्वतंत्र प्रति है।"
मतलब जब एक कर्मचारी वस्तु एक और कस्टम वस्तु रखती है:

Employee e = new Employee(2, "john cena", new Address(12, "West Newbury", "Massachusetts");

फिर आपको 'एड्रेस' ऑब्जेक्ट के साथ-साथ ओवरराइड क्लोन () विधि में क्लोन करने के लिए कोड लिखना होगा। अन्यथा एड्रेस ऑब्जेक्ट क्लोन नहीं होगा और यह एक बग का कारण बनता है जब आप क्लोन किए गए एम्प्लोयी ऑब्जेक्ट में एड्रेस का मूल्य बदलते हैं, जो मूल को भी दर्शाता है।


8
var source = { firstName="Jane", lastname="Jones" };
var shallow = ShallowCopyOf(source);
var deep = DeepCopyOf(source);
source.lastName = "Smith";
WriteLine(source.lastName); // prints Smith
WriteLine(shallow.lastName); // prints Smith
WriteLine(deep.lastName); // prints Jones

यह एक अच्छा उदाहरण नहीं है। उथली प्रतियों का उपयोग ज्यादातर वस्तुओं की त्वरित प्रतिलिपि के लिए किया जाता है, बिना डेटा की प्रतिलिपि बनाए, लेकिन एक बार किसी वस्तु को साझा किए गए डेटा को संशोधित करने की आवश्यकता होती है, तो इसकी एक गहरी प्रतिलिपि ली जाती है। आपका उदाहरण संभवतः शुरुआती लोगों को भ्रमित करेगा।
CMircea

यह केवल उन भाषाओं में काम करता है जो स्ट्रिंग का प्रतिनिधित्व करने के लिए पॉइंटर्स का उपयोग करते हैं। डीएचए जिस बिंदु को बनाने की कोशिश कर रहा है, वह यह है कि उथली प्रतिलिपि केवल समरूप (एकवचन) मूल सामग्री की ओर संकेत करती है, जबकि गहरी प्रतिलिपि बिंदुओं की संदर्भित सामग्री को भी क्लोन करती है। दोनों तरीके सतह की सामग्री की नकल करते हैं। यदि भाषा स्ट्रिंग को शाब्दिक सामग्री के रूप में संग्रहीत करती है, जैसे कि WAV हेडर के अंदर, तो यह उदाहरण काम नहीं करेगा। ध्यान दें कि यह संभवतः अधिकांश वास्तविक जीवन की समस्याओं के लिए बहुत उपयुक्त है जो गूढ़ नहीं हैं।
ड्रैगनलैड

8

गहरी प्रति

एक गहरी प्रतिलिपि सभी क्षेत्रों को कॉपी करती है, और खेतों द्वारा इंगित गतिशील रूप से आवंटित स्मृति की प्रतियां बनाती है। एक गहरी प्रतिलिपि तब होती है जब किसी ऑब्जेक्ट को वस्तुओं के साथ कॉपी किया जाता है, जिसमें यह संदर्भित होता है।

उथली प्रतिलिपि

उथला प्रति एक वस्तु की एक बिट-वार प्रति है। एक नई ऑब्जेक्ट बनाई जाती है जिसमें मूल ऑब्जेक्ट में मानों की एक सटीक प्रतिलिपि होती है। यदि ऑब्जेक्ट का कोई भी फ़ील्ड अन्य ऑब्जेक्ट्स के संदर्भ हैं, तो बस संदर्भ पते कॉपी किए गए हैं, यानी केवल मेमोरी एड्रेस कॉपी किया गया है।


यह लिंक दुख की बात है कि अब काम नहीं करता है - यह अब वेब डिज़ाइन के बारे में फरवरी 2019 के एक लेख की ओर इशारा करता है (जब तक कि लेखक क्लव्वॉयंट नहीं है?)।
फिलफिल

7

उथला कॉपी - मूल और उथली-कॉपी वस्तुओं के अंदर संदर्भ चर में सामान्य वस्तु का संदर्भ होता है।

डीप कॉपी - ओरिजिनल और डीप-कॉपी किए गए ऑब्जेक्ट के अंदर रेफरेंस वेरिएबल में अलग-अलग ऑब्जेक्ट का संदर्भ होता है।

क्लोन हमेशा उथली नकल करता है।

public class Language implements Cloneable{

    String name;
    public Language(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

मुख्य वर्ग निम्नलिखित है-

public static void main(String args[]) throws ClassNotFoundException, CloneNotSupportedException{

      ArrayList<Language> list=new ArrayList<Language>();
      list.add(new Language("C"));
      list.add(new Language("JAVA"));

      ArrayList<Language> shallow=(ArrayList<Language>) list.clone();
      //We used here clone since this always shallow copied.

      System.out.println(list==shallow);

      for(int i=0;i<list.size();i++)
      System.out.println(list.get(i)==shallow.get(i));//true

      ArrayList<Language> deep=new ArrayList<Language>();
      for(Language language:list){
          deep.add((Language) language.clone());
      }
      System.out.println(list==deep);
      for(int i=0;i<list.size();i++)
          System.out.println(list.get(i)==deep.get(i));//false

} 

ऊपर की रूपरेखा होगी-

असत्य सच्चा सच्चा

झूठी झूठी

मूल वस्तु में किया गया कोई भी परिवर्तन उथली वस्तु में प्रतिबिंबित होगा न कि गहरी वस्तु में।

  list.get(0).name="ViSuaLBaSiC";
  System.out.println(shallow.get(0).getName()+"  "+deep.get(0).getName());

आउटपुट- ViSuaLBaSiC सी


7

मैं औपचारिक परिभाषा के बजाय उदाहरण देना चाहूंगा।

var originalObject = { 
    a : 1, 
    b : 2, 
    c : 3,
};

यह कोड उथली प्रति दिखाता है :

var copyObject1 = originalObject;

console.log(copyObject1.a);         // it will print 1 
console.log(originalObject.a);       // it will also print 1 
copyObject1.a = 4; 
console.log(copyObject1.a);           //now it will print 4 
console.log(originalObject.a);       // now it will also print 4

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // now it will print 1

यह कोड एक गहरी प्रतिलिपि दिखाता है :

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // !! now it will print 1 !!

मुझे मिल रहा है1 1 4 4 4 4 4 4
सुरेश प्रजापति

गहरी कॉपी में, copyObject.a = 8 करें और फिर जांचें। आशा है कि आपको उचित उत्तर मिलेगा।
विवेक मेहता

5
struct sample
{
    char * ptr;
}
void shallowcpy(sample & dest, sample & src)
{
    dest.ptr=src.ptr;
}
void deepcpy(sample & dest, sample & src)
{
    dest.ptr=malloc(strlen(src.ptr)+1);
    memcpy(dest.ptr,src.ptr);
}

5

सरल शब्दों में, एक शोलो कॉपी कॉल बाय संदर्भ के समान है और एक डीप कॉपी कॉल बाय वैल्यू के समान है

कॉल बाय रेफरेंस में, किसी फ़ंक्शन के औपचारिक और वास्तविक दोनों पैरामीटर समान मेमोरी लोकेशन और वैल्यू को संदर्भित करते हैं।

कॉल बाय वैल्यू में, फ़ंक्शंस के औपचारिक और वास्तविक दोनों पैरामीटर अलग-अलग मेमोरी लोकेशन को संदर्भित करते हैं, लेकिन समान वैल्यू वाले होते हैं।


5

कल्पना कीजिए कि arr1 और arr2 नामक दो सरणियाँ हैं।

arr1 = arr2;   //shallow copy
arr1 = arr2.clone(); //deep copy

5

उथली प्रति एक नई यौगिक वस्तु का निर्माण करती है और इसके संदर्भों को मूल वस्तु में सम्मिलित करती है।

उथली प्रतिलिपि के विपरीत, डीपकोपी नई यौगिक वस्तु का निर्माण करती है और मूल यौगिक वस्तु की मूल वस्तुओं की प्रतियों को भी सम्मिलित करती है।

एक उदाहरण लेते हैं।

import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)

उपरोक्त कोड FALSE को प्रिंट करता है।

कैसे देखते हैं।

मूल यौगिक वस्तु x=[1,[2]](यौगिक के रूप में कहा जाता है क्योंकि इसमें ऑब्जेक्ट के अंदर ऑब्जेक्ट है (इंसेप्शन))

यहां छवि विवरण दर्ज करें

जैसा कि आप छवि में देख सकते हैं, सूची के अंदर एक सूची है।

फिर हम इसका उपयोग करके एक उथली प्रतिलिपि बनाते हैं y = copy.copy(x)। अजगर यहां क्या करता है, यह एक नई यौगिक वस्तु का निर्माण करेगा लेकिन उनके अंदर की वस्तुएं ओरिग्नेंट ऑब्जेक्ट्स की ओर इशारा करती हैं।

यहां छवि विवरण दर्ज करें

छवि में इसने बाहरी सूची के लिए एक नई प्रतिलिपि बनाई है। लेकिन आंतरिक सूची मूल के समान ही रहती है।

अब हम इसका उपयोग करके डीपकोपी बनाते हैं z = copy.deepcopy(x)। अजगर यहाँ क्या करता है, यह बाहरी सूची के साथ-साथ आंतरिक सूची के लिए नई वस्तु का निर्माण करेगा। जैसा कि नीचे दी गई छवि में दिखाया गया है (लाल हाइलाइट किया गया)।

यहां छवि विवरण दर्ज करें

अंत कोड प्रिंट में False, चूंकि y और z समान ऑब्जेक्ट नहीं हैं।

HTH।


2

उथला नकल एक नई वस्तु बना रहा है और फिर वर्तमान वस्तु के गैर-स्थिर क्षेत्रों को नई वस्तु में कॉपी कर रहा है। यदि कोई फ़ील्ड मान प्रकार है -> फ़ील्ड की बिट-बाय-बिट प्रतिलिपि की जाती है; एक संदर्भ प्रकार के लिए -> संदर्भ की प्रतिलिपि बनाई गई है लेकिन संदर्भित वस्तु नहीं है; इसलिए मूल वस्तु और उसका क्लोन एक ही वस्तु को संदर्भित करता है।

डीप कॉपी एक नई वस्तु बना रहा है और फिर वर्तमान ऑब्जेक्ट के नॉनस्टैटिक फील्ड्स को नई ऑब्जेक्ट में कॉपी कर रहा है। यदि कोई फ़ील्ड मान प्रकार है -> फ़ील्ड की बिट-बाय-बिट प्रतिलिपि की जाती है। यदि कोई फ़ील्ड एक संदर्भ प्रकार है -> संदर्भित ऑब्जेक्ट की एक नई प्रतिलिपि निष्पादित की जाती है। क्लोन किए जाने वाले वर्गों को [क्रमिक] के रूप में चिह्नित किया जाना चाहिए।


2

[ब्लॉग] से लिया गया: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

डीप कॉपी में एक ही वर्ग के दूसरे उदाहरण को बनाने के लिए एक वस्तु की सामग्री का उपयोग करना शामिल है। एक गहरी प्रति में, दोनों वस्तुओं में ht समान जानकारी हो सकती है, लेकिन लक्ष्य वस्तु के अपने बफ़र्स और संसाधन होंगे। किसी भी वस्तु का विनाश शेष वस्तु को प्रभावित नहीं करेगा। अतिभारित असाइनमेंट ऑपरेटर वस्तुओं की एक गहरी प्रतिलिपि बनाएगा।

उथला कॉपी में एक ही वर्ग के दूसरे उदाहरण में एक वस्तु की सामग्री की नकल करना शामिल है, जिससे दर्पण छवि बनती है। संदर्भों और बिंदुओं की सीधी नकल करने के कारण, दोनों वस्तुएं अन्य वस्तु की एक ही बाहरी सामग्री को अप्रत्याशित रूप से साझा करेंगी।

स्पष्टीकरण:

कॉपी कंस्ट्रक्टर का उपयोग करके हम केवल सदस्य द्वारा डेटा वैल्यूज को कॉपी करते हैं। नकल करने की इस विधि को उथली प्रतिलिपि कहा जाता है। यदि ऑब्जेक्ट एक साधारण वर्ग है, तो इसमें निर्मित प्रकार शामिल हैं और कोई भी संकेत स्वीकार्य नहीं होगा। यह फ़ंक्शन मानों और ऑब्जेक्ट्स का उपयोग करेगा और इसका व्यवहार उथली प्रतिलिपि के साथ नहीं बदला जाएगा, केवल उन पॉइंटर्स के पते जो कि सदस्य हैं कॉपी किए गए हैं और न कि मान जो इंगित कर रहा है। ऑब्जेक्ट के डेटा मान तब अनजाने में फ़ंक्शन द्वारा बदल दिए जाएंगे। जब फ़ंक्शन कार्यक्षेत्र से बाहर हो जाता है, तो उसके सभी डेटा के साथ ऑब्जेक्ट की प्रतिलिपि स्टैक से पॉप अप हो जाती है।

यदि ऑब्जेक्ट में कोई संकेत है, तो एक गहरी प्रतिलिपि को निष्पादित करने की आवश्यकता है। किसी ऑब्जेक्ट की गहरी प्रतिलिपि के साथ, मेमोरी को फ्री स्टोर में ऑब्जेक्ट के लिए आवंटित किया जाता है और इंगित किए गए तत्वों को कॉपी किया जाता है। एक गहरी प्रतिलिपि का उपयोग उन वस्तुओं के लिए किया जाता है जो किसी फ़ंक्शन से लौटाए जाते हैं।


2

अन्य उत्तरों में अधिक जोड़ने के लिए,

  • किसी वस्तु की शॉल कॉपी मूल्य प्रकार आधारित गुणों के लिए मूल्य द्वारा कॉपी करता है, और संदर्भ प्रकार आधारित गुणों के लिए संदर्भ द्वारा कॉपी करता है।
  • किसी वस्तु की गहरी प्रतिलिपि मूल्य प्रकार आधारित गुणों के लिए मूल्य द्वारा प्रतिलिपि प्रस्तुत करती है, साथ ही संदर्भ प्रकार आधारित गुणों के लिए मूल्य की प्रतिलिपि पदानुक्रम में (संदर्भ प्रकारों में) गहरी होती है

2

उथला प्रति नया संदर्भ नहीं बनाएगा, लेकिन गहरी प्रति नया संदर्भ बनाएगी।

यहाँ गहरी और उथली प्रति समझाने का कार्यक्रम है।

public class DeepAndShollowCopy {
    int id;
    String name;
    List<String> testlist = new ArrayList<>();

    /*
    // To performing Shallow Copy 
    // Note: Here we are not creating any references. 
      public DeepAndShollowCopy(int id, String name, List<String>testlist)
       { 

       System.out.println("Shallow Copy for Object initialization");
       this.id = id; 
       this.name = name; 
       this.testlist = testlist; 

       }
    */  

    // To performing Deep Copy 
    // Note: Here we are creating one references( Al arraylist object ). 
    public DeepAndShollowCopy(int id, String name, List<String> testlist) {
        System.out.println("Deep Copy for Object initialization");
        this.id = id;
        this.name = name;
        String item;
        List<String> Al = new ArrayList<>();
        Iterator<String> itr = testlist.iterator();
        while (itr.hasNext()) {
            item = itr.next();
            Al.add(item);
        }
        this.testlist = Al;
    }


    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Oracle");
        list.add("C++");
        DeepAndShollowCopy copy=new DeepAndShollowCopy(10,"Testing", list);
        System.out.println(copy.toString());
    }
    @Override
    public String toString() {
        return "DeepAndShollowCopy [id=" + id + ", name=" + name + ", testlist=" + testlist + "]";
    }
}

1

प्रतिलिपि बनाई जा रही है:

सरणी एक वर्ग है, जिसका अर्थ है कि यह संदर्भ प्रकार है इसलिए array1 = array2 परिणाम दो चर में हैं जो एक ही सरणी को संदर्भित करते हैं।

लेकिन इस उदाहरण को देखें:

  static void Main()
    {
        int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; 
        int[] arr2 = new int[] { 6, 7, 8, 9, 0 };

        Console.WriteLine(arr1[2] + " " + arr2[2]);
        arr2 = arr1;
        Console.WriteLine(arr1[2] + " " + arr2[2]); 
        arr2 = (int[])arr1.Clone();
        arr1[2] = 12;
        Console.WriteLine(arr1[2] + " " + arr2[2]);
    }

उथले क्लोन का मतलब है कि क्लोन की गई सरणी द्वारा दर्शाई गई केवल मेमोरी की प्रतिलिपि बनाई गई है।

यदि सरणी में मान प्रकार ऑब्जेक्ट होते हैं, तो मान कॉपी किए जाते हैं ;

यदि सरणी में संदर्भ प्रकार होता है, तो केवल संदर्भ की प्रतिलिपि बनाई जाती है - इसलिए परिणामस्वरूप दो सरणियाँ होती हैं जिनके सदस्य समान वस्तुओं का संदर्भ देते हैं

एक गहरी प्रति बनाने के लिए - जहां संदर्भ प्रकार की नकल की जाती है, आपको सरणी के माध्यम से लूप करना चाहिए और प्रत्येक तत्व को मैन्युअल रूप से क्लोन करना होगा।


मुझे अन्य भाषाओं के बारे में जानकारी नहीं है, लेकिन C # / VB में, उथले मूल्य प्रकारों की एक कॉपी करने से मूल्यों की प्रतिलिपि नहीं बनती है। दो सरणियाँ समान वस्तुओं को संदर्भित करती हैं। एक फ़ॉर्म में एक बटन जोड़ें और इस कोड को देखने के लिए जोड़ें:private void button1_Click(object sender, EventArgs e) { int[] arr1 = new int[]{1,2,3,4,5}; int[] arr2 = new int[]{6,7,8,9,0}; MessageBox.Show(arr1[2] + " " + arr2[2]); arr2 = arr1; MessageBox.Show(arr1[2] + " " + arr2[2]); arr1[2] = 12; MessageBox.Show(arr1[2] + " " + arr2[2]); }
डीनॉक

आप सही हैं, मैंने सरणियों पर क्लोन का उपयोग करते हुए मेरे उत्तर को अधिक सटीक बताया। आप पूरी तरह से सही हैं कि "उथले मूल्य प्रकारों की नकल मानों की नकल नहीं करता है", लेकिन सरणी पर क्लोन का उपयोग करता है। मैंने समझाने की कोशिश की है, कोशिश करो। धन्यवाद
lukaszk

1

मुझे निम्नलिखित पंक्तियों से समझ में आया।

ऑब्जेक्ट और ऑब्जेक्ट के रेफरेंस टाइप (स्ट्रिंग, क्लास आदि) को टारगेट कॉपी करने के लिए शॉलो एक ऑब्जेक्ट वैल्यू टाइप (इंट, फ्लोट, बूल) फील्ड्स को कॉपी करता है और उसे टारगेट ऑब्जेक्ट में रेफरेंस के रूप में कॉपी किया जाता है । इस लक्ष्य में संदर्भ प्रकार स्रोत ऑब्जेक्ट की मेमोरी लोकेशन की ओर इशारा करते हैं।

डीप कॉपी ऑब्जेक्ट की वैल्यू और रेफरेंस टाइप्स को टारगेट ऑब्जेक्ट्स की पूरी नई कॉपी में कॉपी करता है। इसका मतलब है कि मूल्य प्रकार और संदर्भ प्रकार दोनों को एक नया मेमोरी स्थान आवंटित किया जाएगा।


0

उपरोक्त सभी परिभाषाओं में, एक और सबसे अधिक उपयोग की जाने वाली गहरी कॉपी, क्लास के कॉपी कंस्ट्रक्टर (या ओवरलोडिंग असाइनमेंट ऑप्रेटर) में है।

उथला कॉपी -> जब आप कॉपी कंस्ट्रक्टर प्रदान नहीं कर रहे हैं। यहां, केवल ऑब्जेक्ट की प्रतिलिपि बनाई जाती है, लेकिन कक्षा के सभी सदस्यों की प्रतिलिपि नहीं बनाई जाती है।

डीप कॉपी -> वह है जब आपने अपनी क्लास में कॉपी कंस्ट्रक्टर या ओवरलोड असाइनमेंट को लागू करने का निर्णय लिया है और क्लास के सभी सदस्यों को कॉपी करने की अनुमति देता है।

MyClass& MyClass(const MyClass& obj) // copy constructor for MyClass
{
          // write your code, to copy all the members and return the new object
}
MyClass& operator=(const MyClass& obj) // overloading assignment operator,
{
          // write your code, to copy all the members and return the new object
}

0

कॉपी कंस्ट्रक्टर का उपयोग उसी वर्ग के पहले से निर्मित ऑब्जेक्ट के साथ नई ऑब्जेक्ट को इनिशियलाइज़ करने के लिए किया जाता है। डिफ़ॉल्ट रूप से संकलक ने उथली प्रति लिखी। जब डायनमिक मेमोरी एलोकेशन शामिल नहीं होता है तो शॉलो कॉपी ठीक काम करती है क्योंकि जब डायनेमिक मेमोरी एलोकेशन शामिल होती है तो दोनों ऑब्जेक्ट्स एक ही मेमोरी लोकेशन को एक हीप में इंगित करते हैं, इसलिए इस समस्या को दूर करने के लिए हमने डीप कॉपी लिखी है ताकि दोनों ऑब्जेक्ट्स की अपनी-अपनी विशेषताओं की कॉपी हो एक स्मृति में। संपूर्ण उदाहरणों और स्पष्टीकरणों के साथ विवरण पढ़ने के लिए आप लेख C ++ कंस्ट्रक्टर देख सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.