गहरी प्रति और उथली प्रति के बीच क्या अंतर है?
गहरी प्रति और उथली प्रति के बीच क्या अंतर है?
जवाबों:
उथले नकल के रूप में संभव के रूप में थोड़ा नकल। संग्रह की उथली प्रतिलिपि संग्रह संरचना की एक प्रति है, तत्वों की नहीं। उथली प्रतिलिपि के साथ, दो संग्रह अब व्यक्तिगत तत्वों को साझा करते हैं।
गहरी नकलें सब कुछ नकल करती हैं। एक संग्रह की एक गहरी प्रतिलिपि दो संग्रह है जिसमें मूल संग्रह के सभी तत्वों को दोहराया गया है।
चौड़ाई बनाम गहराई; जड़ नोड के रूप में अपनी वस्तु के साथ संदर्भ के एक पेड़ के संदर्भ में सोचो।
उथला:
चर ए और बी स्मृति के विभिन्न क्षेत्रों को संदर्भित करते हैं, जब बी को ए को सौंपा जाता है दो चर स्मृति के एक ही क्षेत्र को संदर्भित करते हैं। बाद में या तो सामग्री में संशोधन दूसरे की सामग्री में तुरंत परिलक्षित होता है, क्योंकि वे सामग्री साझा करते हैं।
दीप:
चर A और B स्मृति के विभिन्न क्षेत्रों को संदर्भित करते हैं, जब B को A स्मृति क्षेत्र में उन मानों को सौंपा जाता है जिन्हें A बिंदुओं में स्मृति क्षेत्र में कॉपी किया जाता है। बाद में या तो ए या बी के लिए अद्वितीय सामग्री में संशोधन; सामग्री साझा नहीं कर रहे हैं।
संक्षेप में, यह इस बात पर निर्भर करता है कि कौन से बिंदु क्या हैं। उथली प्रतिलिपि में, ऑब्जेक्ट B स्मृति में ऑब्जेक्ट A के स्थान को इंगित करता है। डीप कॉपी में ऑब्जेक्ट ए की मेमोरी लोकेशन में सभी चीजें ऑब्जेक्ट बी की मेमोरी लोकेशन पर कॉपी हो जाती हैं।
इस विकी लेख में एक महान आरेख है।
निम्नलिखित छवि पर विचार करने का प्रयास करें
उदाहरण के लिए Object.MemberwiseClone एक उथली प्रतिलिपि लिंक बनाता है
और ICloneable इंटरफ़ेस का उपयोग करके आप यहां बताए अनुसार गहरी प्रतिलिपि प्राप्त कर सकते हैं
विशेष रूप से iOS डेवलपर्स के लिए:
यदि B
एक उथली प्रतिलिपि है A
, तो आदिम डेटा के लिए यह पसंद है B = [A assign];
और वस्तुओं के लिए यह पसंद है B = [A retain]
;
B और A एक ही मेमोरी लोकेशन की ओर इशारा करते हैं
अगर B
की एक गहरी प्रतिलिपि है A
, तो यह पसंद हैB = [A copy];
B और A अलग-अलग मेमोरी लोकेशन की ओर इशारा करते हैं
B मेमोरी एड्रेस A के समान है
B में A की समान सामग्री है
उथली प्रतिलिपि: सदस्य मानों को एक वस्तु से दूसरी वस्तु में कॉपी करता है।
डीप कॉपी: सदस्य मान को एक ऑब्जेक्ट से दूसरे ऑब्जेक्ट में कॉपी करता है।
कोई भी पॉइंटर ऑब्जेक्ट डुप्लिकेट और डीप कॉपिड हैं।
उदाहरण:
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.)
मैंने यहाँ उत्तर को समझने के लिए छोटा, आसान नहीं देखा है - इसलिए मैं इसे आज़माऊँगा।
उथली प्रतिलिपि के साथ, स्रोत द्वारा इंगित की गई कोई भी वस्तु भी गंतव्य द्वारा इंगित की जाती है (ताकि कोई संदर्भित वस्तुओं की नकल न हो)।
एक गहरी प्रतिलिपि के साथ, स्रोत द्वारा इंगित की गई किसी भी वस्तु को कॉपी किया जाता है और प्रतिलिपि गंतव्य द्वारा इंगित की जाती है (इसलिए अब प्रत्येक संदर्भित ऑब्जेक्ट में से 2 होंगे)। यह वस्तु के पेड़ को गिरा देता है।
बस इस समझ के लिए आप इस लेख का अनुसरण कर सकते हैं: https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm
उथली प्रतिलिपि:
गहरी प्रति:
{दो वस्तुओं की कल्पना करें: 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 ++ ट्यूटोरियल सामान) के लिए कुछ प्रदर्शित कर रहे हैं तो यह ठीक है। लेकिन अगर आप निगरानी और पहचान प्रणाली, या सोनार ट्रैकिंग सिस्टम जैसे कोई एप्लिकेशन चला रहे हैं, तो आप उथले को अपनी वस्तुओं की नकल करते हुए रखने वाले नहीं हैं क्योंकि यह आपके प्रोग्राम को जल्दी या बाद में मार देगा।
char * Source = "Hello, world.";
char * ShallowCopy = Source;
char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);
'ShallowCopy' स्मृति में उसी स्थान की ओर इंगित करता है जैसा 'स्रोत' करता है। 'डीपकोपी' स्मृति में एक अलग स्थान पर इंगित करता है, लेकिन सामग्री समान हैं।
शॉल कॉपी क्या है?
उथला प्रति एक वस्तु की एक बिट-वार प्रति है। एक नई ऑब्जेक्ट बनाई जाती है जिसमें मूल ऑब्जेक्ट में मानों की एक सटीक प्रतिलिपि होती है। यदि ऑब्जेक्ट का कोई भी फ़ील्ड अन्य ऑब्जेक्ट्स के संदर्भ हैं, तो केवल संदर्भ पते कॉपी किए गए हैं, यानी केवल मेमोरी एड्रेस कॉपी किया गया है।
इस आकृति में, प्रकार के MainObject1
क्षेत्र field1
int के हैं, और ContainObject1
प्रकार के ContainObject
। जब आप की एक उथली प्रतिलिपि करते हैं MainObject1
, की प्रतिलिपि बनाई गई मान युक्त और अभी भी खुद को इंगित करने MainObject2
के साथ बनाई field2
गई है। ध्यान दें कि चूंकि यह आदिम प्रकार का है, इसलिए इसके मूल्य की नकल की जाती है , क्योंकि यह एक वस्तु है, फिर भी इंगित करता है । में किए गए बदलाव तो में में परिलक्षित होगा ।field1
ContainObject1
field1
field2
ContainedObject1
MainObject2
ContainObject1
ContainObject1
MainObject1
MainObject2
अब अगर यह उथली प्रति है, तो देखते हैं कि गहरी प्रति क्या है?
डीप कॉपी क्या है?
एक गहरी प्रतिलिपि सभी क्षेत्रों को कॉपी करती है, और खेतों द्वारा इंगित गतिशील रूप से आवंटित स्मृति की प्रतियां बनाती है। एक गहरी प्रतिलिपि तब होती है जब किसी ऑब्जेक्ट को वस्तुओं के साथ कॉपी किया जाता है, जिसमें यह संदर्भित होता है।
इस चित्र में, MainObject1 क्षेत्रों के field1
प्रकार int की, और ContainObject1
के प्रकार के ContainObject
। आप की एक गहरी प्रतिलिपि करते हैं MainObject1
, MainObject2
के साथ बनाई गई है field2
की प्रतिलिपि बनाई मूल्य युक्त field1
और ContainObject2
की प्रतिलिपि बनाई मूल्य युक्त ContainObject1
। में किए गए बदलाव नोट ContainObject1
में MainObject1
में दिखाई नहीं देगा MainObject2
।
field3
, जब उस मुद्दे के रूप में कुछ करने की कोशिश करने और समझने की स्थिति में होता है, उस उदाहरण में # 3 कहां हो रहा है ContainObject2
?
ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में, एक प्रकार में सदस्य फ़ील्ड्स का संग्रह शामिल है। इन फ़ील्ड्स को या तो मान या संदर्भ द्वारा संग्रहीत किया जा सकता है (अर्थात, मान के लिए एक संकेतक)।
उथली प्रतिलिपि में, प्रकार का एक नया उदाहरण बनाया जाता है और मूल्यों को नए उदाहरण में कॉपी किया जाता है। संदर्भ बिंदु भी मानों की तरह ही कॉपी किए जाते हैं। इसलिए, संदर्भ मूल वस्तुओं की ओर इशारा कर रहे हैं। संदर्भ द्वारा संग्रहीत सदस्यों में कोई भी परिवर्तन मूल और प्रतिलिपि दोनों में दिखाई देते हैं, क्योंकि कोई भी प्रतिलिपि संदर्भित ऑब्जेक्ट से नहीं बनाई गई थी।
एक गहरी प्रतिलिपि में, मूल्य द्वारा संग्रहीत फ़ील्ड पहले की तरह कॉपी किए जाते हैं, लेकिन संदर्भ द्वारा संग्रहीत ऑब्जेक्ट के लिए पॉइंटर्स कॉपी नहीं किए जाते हैं। इसके बजाय, एक गहरी प्रतिलिपि संदर्भित ऑब्जेक्ट से बना है, और नई ऑब्जेक्ट के लिए एक पॉइंटर संग्रहीत है। उन संदर्भित वस्तुओं में किए गए कोई भी परिवर्तन ऑब्जेक्ट की अन्य प्रतियों को प्रभावित नहीं करेंगे।
'ShallowCopy' स्मृति में उसी स्थान की ओर इंगित करता है जैसा 'स्रोत' करता है। 'डीपकोपी' स्मृति में एक अलग स्थान पर इंगित करता है, लेकिन सामग्री समान हैं।
उथला क्लोनिंग:
परिभाषा: "किसी वस्तु की उथली प्रतिलिपि 'मुख्य' ऑब्जेक्ट की प्रतिलिपि बनाती है, लेकिन आंतरिक वस्तुओं की प्रतिलिपि नहीं बनाती है।" जब एक कस्टम ऑब्जेक्ट (उदाहरण। कर्मचारी) में सिर्फ आदिम, स्ट्रिंग प्रकार चर होते हैं, तो आप 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");
फिर आपको 'एड्रेस' ऑब्जेक्ट के साथ-साथ ओवरराइड क्लोन () विधि में क्लोन करने के लिए कोड लिखना होगा। अन्यथा एड्रेस ऑब्जेक्ट क्लोन नहीं होगा और यह एक बग का कारण बनता है जब आप क्लोन किए गए एम्प्लोयी ऑब्जेक्ट में एड्रेस का मूल्य बदलते हैं, जो मूल को भी दर्शाता है।
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
गहरी प्रति
एक गहरी प्रतिलिपि सभी क्षेत्रों को कॉपी करती है, और खेतों द्वारा इंगित गतिशील रूप से आवंटित स्मृति की प्रतियां बनाती है। एक गहरी प्रतिलिपि तब होती है जब किसी ऑब्जेक्ट को वस्तुओं के साथ कॉपी किया जाता है, जिसमें यह संदर्भित होता है।
उथली प्रतिलिपि
उथला प्रति एक वस्तु की एक बिट-वार प्रति है। एक नई ऑब्जेक्ट बनाई जाती है जिसमें मूल ऑब्जेक्ट में मानों की एक सटीक प्रतिलिपि होती है। यदि ऑब्जेक्ट का कोई भी फ़ील्ड अन्य ऑब्जेक्ट्स के संदर्भ हैं, तो बस संदर्भ पते कॉपी किए गए हैं, यानी केवल मेमोरी एड्रेस कॉपी किया गया है।
उथला कॉपी - मूल और उथली-कॉपी वस्तुओं के अंदर संदर्भ चर में सामान्य वस्तु का संदर्भ होता है।
डीप कॉपी - ओरिजिनल और डीप-कॉपी किए गए ऑब्जेक्ट के अंदर रेफरेंस वेरिएबल में अलग-अलग ऑब्जेक्ट का संदर्भ होता है।
क्लोन हमेशा उथली नकल करता है।
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 सी
मैं औपचारिक परिभाषा के बजाय उदाहरण देना चाहूंगा।
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
सरल शब्दों में, एक शोलो कॉपी कॉल बाय संदर्भ के समान है और एक डीप कॉपी कॉल बाय वैल्यू के समान है
कॉल बाय रेफरेंस में, किसी फ़ंक्शन के औपचारिक और वास्तविक दोनों पैरामीटर समान मेमोरी लोकेशन और वैल्यू को संदर्भित करते हैं।
कॉल बाय वैल्यू में, फ़ंक्शंस के औपचारिक और वास्तविक दोनों पैरामीटर अलग-अलग मेमोरी लोकेशन को संदर्भित करते हैं, लेकिन समान वैल्यू वाले होते हैं।
उथली प्रति एक नई यौगिक वस्तु का निर्माण करती है और इसके संदर्भों को मूल वस्तु में सम्मिलित करती है।
उथली प्रतिलिपि के विपरीत, डीपकोपी नई यौगिक वस्तु का निर्माण करती है और मूल यौगिक वस्तु की मूल वस्तुओं की प्रतियों को भी सम्मिलित करती है।
एक उदाहरण लेते हैं।
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।
उथला नकल एक नई वस्तु बना रहा है और फिर वर्तमान वस्तु के गैर-स्थिर क्षेत्रों को नई वस्तु में कॉपी कर रहा है। यदि कोई फ़ील्ड मान प्रकार है -> फ़ील्ड की बिट-बाय-बिट प्रतिलिपि की जाती है; एक संदर्भ प्रकार के लिए -> संदर्भ की प्रतिलिपि बनाई गई है लेकिन संदर्भित वस्तु नहीं है; इसलिए मूल वस्तु और उसका क्लोन एक ही वस्तु को संदर्भित करता है।
डीप कॉपी एक नई वस्तु बना रहा है और फिर वर्तमान ऑब्जेक्ट के नॉनस्टैटिक फील्ड्स को नई ऑब्जेक्ट में कॉपी कर रहा है। यदि कोई फ़ील्ड मान प्रकार है -> फ़ील्ड की बिट-बाय-बिट प्रतिलिपि की जाती है। यदि कोई फ़ील्ड एक संदर्भ प्रकार है -> संदर्भित ऑब्जेक्ट की एक नई प्रतिलिपि निष्पादित की जाती है। क्लोन किए जाने वाले वर्गों को [क्रमिक] के रूप में चिह्नित किया जाना चाहिए।
[ब्लॉग] से लिया गया: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
डीप कॉपी में एक ही वर्ग के दूसरे उदाहरण को बनाने के लिए एक वस्तु की सामग्री का उपयोग करना शामिल है। एक गहरी प्रति में, दोनों वस्तुओं में ht समान जानकारी हो सकती है, लेकिन लक्ष्य वस्तु के अपने बफ़र्स और संसाधन होंगे। किसी भी वस्तु का विनाश शेष वस्तु को प्रभावित नहीं करेगा। अतिभारित असाइनमेंट ऑपरेटर वस्तुओं की एक गहरी प्रतिलिपि बनाएगा।
उथला कॉपी में एक ही वर्ग के दूसरे उदाहरण में एक वस्तु की सामग्री की नकल करना शामिल है, जिससे दर्पण छवि बनती है। संदर्भों और बिंदुओं की सीधी नकल करने के कारण, दोनों वस्तुएं अन्य वस्तु की एक ही बाहरी सामग्री को अप्रत्याशित रूप से साझा करेंगी।
स्पष्टीकरण:
कॉपी कंस्ट्रक्टर का उपयोग करके हम केवल सदस्य द्वारा डेटा वैल्यूज को कॉपी करते हैं। नकल करने की इस विधि को उथली प्रतिलिपि कहा जाता है। यदि ऑब्जेक्ट एक साधारण वर्ग है, तो इसमें निर्मित प्रकार शामिल हैं और कोई भी संकेत स्वीकार्य नहीं होगा। यह फ़ंक्शन मानों और ऑब्जेक्ट्स का उपयोग करेगा और इसका व्यवहार उथली प्रतिलिपि के साथ नहीं बदला जाएगा, केवल उन पॉइंटर्स के पते जो कि सदस्य हैं कॉपी किए गए हैं और न कि मान जो इंगित कर रहा है। ऑब्जेक्ट के डेटा मान तब अनजाने में फ़ंक्शन द्वारा बदल दिए जाएंगे। जब फ़ंक्शन कार्यक्षेत्र से बाहर हो जाता है, तो उसके सभी डेटा के साथ ऑब्जेक्ट की प्रतिलिपि स्टैक से पॉप अप हो जाती है।
यदि ऑब्जेक्ट में कोई संकेत है, तो एक गहरी प्रतिलिपि को निष्पादित करने की आवश्यकता है। किसी ऑब्जेक्ट की गहरी प्रतिलिपि के साथ, मेमोरी को फ्री स्टोर में ऑब्जेक्ट के लिए आवंटित किया जाता है और इंगित किए गए तत्वों को कॉपी किया जाता है। एक गहरी प्रतिलिपि का उपयोग उन वस्तुओं के लिए किया जाता है जो किसी फ़ंक्शन से लौटाए जाते हैं।
अन्य उत्तरों में अधिक जोड़ने के लिए,
उथला प्रति नया संदर्भ नहीं बनाएगा, लेकिन गहरी प्रति नया संदर्भ बनाएगी।
यहाँ गहरी और उथली प्रति समझाने का कार्यक्रम है।
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 + "]";
}
}
प्रतिलिपि बनाई जा रही है:
सरणी एक वर्ग है, जिसका अर्थ है कि यह संदर्भ प्रकार है इसलिए 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]);
}
उथले क्लोन का मतलब है कि क्लोन की गई सरणी द्वारा दर्शाई गई केवल मेमोरी की प्रतिलिपि बनाई गई है।
यदि सरणी में मान प्रकार ऑब्जेक्ट होते हैं, तो मान कॉपी किए जाते हैं ;
यदि सरणी में संदर्भ प्रकार होता है, तो केवल संदर्भ की प्रतिलिपि बनाई जाती है - इसलिए परिणामस्वरूप दो सरणियाँ होती हैं जिनके सदस्य समान वस्तुओं का संदर्भ देते हैं ।
एक गहरी प्रति बनाने के लिए - जहां संदर्भ प्रकार की नकल की जाती है, आपको सरणी के माध्यम से लूप करना चाहिए और प्रत्येक तत्व को मैन्युअल रूप से क्लोन करना होगा।
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]); }
मुझे निम्नलिखित पंक्तियों से समझ में आया।
ऑब्जेक्ट और ऑब्जेक्ट के रेफरेंस टाइप (स्ट्रिंग, क्लास आदि) को टारगेट कॉपी करने के लिए शॉलो एक ऑब्जेक्ट वैल्यू टाइप (इंट, फ्लोट, बूल) फील्ड्स को कॉपी करता है और उसे टारगेट ऑब्जेक्ट में रेफरेंस के रूप में कॉपी किया जाता है । इस लक्ष्य में संदर्भ प्रकार स्रोत ऑब्जेक्ट की मेमोरी लोकेशन की ओर इशारा करते हैं।
डीप कॉपी ऑब्जेक्ट की वैल्यू और रेफरेंस टाइप्स को टारगेट ऑब्जेक्ट्स की पूरी नई कॉपी में कॉपी करता है। इसका मतलब है कि मूल्य प्रकार और संदर्भ प्रकार दोनों को एक नया मेमोरी स्थान आवंटित किया जाएगा।
उपरोक्त सभी परिभाषाओं में, एक और सबसे अधिक उपयोग की जाने वाली गहरी कॉपी, क्लास के कॉपी कंस्ट्रक्टर (या ओवरलोडिंग असाइनमेंट ऑप्रेटर) में है।
उथला कॉपी -> जब आप कॉपी कंस्ट्रक्टर प्रदान नहीं कर रहे हैं। यहां, केवल ऑब्जेक्ट की प्रतिलिपि बनाई जाती है, लेकिन कक्षा के सभी सदस्यों की प्रतिलिपि नहीं बनाई जाती है।
डीप कॉपी -> वह है जब आपने अपनी क्लास में कॉपी कंस्ट्रक्टर या ओवरलोड असाइनमेंट को लागू करने का निर्णय लिया है और क्लास के सभी सदस्यों को कॉपी करने की अनुमति देता है।
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
}
कॉपी कंस्ट्रक्टर का उपयोग उसी वर्ग के पहले से निर्मित ऑब्जेक्ट के साथ नई ऑब्जेक्ट को इनिशियलाइज़ करने के लिए किया जाता है। डिफ़ॉल्ट रूप से संकलक ने उथली प्रति लिखी। जब डायनमिक मेमोरी एलोकेशन शामिल नहीं होता है तो शॉलो कॉपी ठीक काम करती है क्योंकि जब डायनेमिक मेमोरी एलोकेशन शामिल होती है तो दोनों ऑब्जेक्ट्स एक ही मेमोरी लोकेशन को एक हीप में इंगित करते हैं, इसलिए इस समस्या को दूर करने के लिए हमने डीप कॉपी लिखी है ताकि दोनों ऑब्जेक्ट्स की अपनी-अपनी विशेषताओं की कॉपी हो एक स्मृति में। संपूर्ण उदाहरणों और स्पष्टीकरणों के साथ विवरण पढ़ने के लिए आप लेख C ++ कंस्ट्रक्टर देख सकते हैं ।