سؤال

ما الفرق بين النسخة العميقة والنسخة الضحلة؟

هل كانت مفيدة؟

المحلول

ونسخ مكررة الضحلة أقل قدر ممكن. نسخة الضحلة من مجموعة هي نسخة من بنية جمع، وليس العناصر. مع نسخة الضحلة، مجموعتين الآن تبادل العناصر الفردية.

ونسخ مكررة العميقة كل شيء. صورة عميقة لجمع هي مجموعتين مع كل من العناصر الموجودة في المجموعة الأصلية تكرار.

نصائح أخرى

واتساع مقابل العمق. التفكير في شجرة من المراجع مع الكائن كما عقدة الجذر.

والضحلة:

والمتغيرات A و B يشير إلى مناطق مختلفة من الذاكرة، عندما تم تعيينه B إلى A تشير المتغيرين إلى نفس المنطقة من الذاكرة. تنعكس التعديلات في وقت لاحق إلى محتويات إما على الفور في محتويات البعض، كما أنها تشترك المحتويات.

وديب:

والمتغيرات A و B يشير إلى مناطق مختلفة من الذاكرة، عندما تم تعيينه B إلى A القيم في منطقة الذاكرة التي A نقطة ليتم نسخ في منطقة الذاكرة التي نقاط B. لا تزال تعديلات لاحقة على محتويات إما فريدة من نوعها لA أو B، لا يتم مشاركة المحتويات.

وباختصار، فإنه يعتمد على ما يشير إلى ما. في نسخة الضحلة، ونقاط الكائن B الاعتراض موقع A في الذاكرة. في نسخة عميق، كل شيء في وجوه A في موقع الذاكرة الحصول على نسخ الاعتراض موقع الذاكرة ب.

وهذه المادة ويكي لديها مخطط كبير.

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

خاصة لمطوري iOS:

لو B هو نسخة سطحية ل A, ، ثم بالنسبة للبيانات البدائية يكون الأمر كذلك B = [A assign]; وبالنسبة للأشياء فهو مثل B = [A retain];

يشير B وA إلى نفس موقع الذاكرة

لو B هو نسخة عميقة ل A, ، فهو مثل B = [A copy];

يشير B وA إلى مواقع ذاكرة مختلفة

عنوان الذاكرة B هو نفس عنوان الذاكرة A

يحتوي B على نفس محتويات A

حاول أن تفكر في الصورة التالية

enter image description here

على سبيل المثال Object.MemberwiseClone يخلق أ أجوف ينسخ وصلة

واستخدام ICloneable الواجهة التي يمكنك الحصول عليها عميق نسخ كما هو موضح هنا

والضحلة نسخة: نسخ القيم عضو من كائن واحد إلى آخر

نسخ ديب: نسخ القيم عضو من كائن واحد إلى آخر
يتم تكرار أي أجسام مؤشر وديب نسخها.

مثال:

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 من كل الكائن المشار إليه). هذا recurses أسفل شجرة الكائن.

ولتسهيل الفهم يمكنك متابعة هذا المقال:https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm


نسخة سطحية:

Shallow Copy


نسخة عميقة:

Deep Copy

{تخيل شيئين:A وB من نفس النوع _t(فيما يتعلق بـ C++) وأنت تفكر في النسخ السطحي/العميق من A إلى B}

نسخة سطحية:ما عليك سوى إنشاء نسخة من المرجع إلى A إلى B.فكر في الأمر كنسخة من عنوان "أ".لذا، سيكون عنوانا A وB هو نفسه، أي.سوف يشيرون إلى نفس موقع الذاكرة، أي.محتويات البيانات.

نسخة عميقة:ما عليك سوى عمل نسخة من جميع أعضاء A، وتخصيص الذاكرة في موقع مختلف لـ B ثم تعيين الأعضاء المنسوخة إلى B لتحقيق نسخة عميقة.وبهذه الطريقة، إذا أصبح A غير موجود فإن B يظل صالحًا في الذاكرة.المصطلح الصحيح الذي يجب استخدامه هو الاستنساخ، حيث تعلم أن كلاهما متماثلان تمامًا، لكنهما مختلفان (على سبيل المثال.المخزنة ككيانين مختلفين في مساحة الذاكرة).يمكنك أيضًا توفير غلاف النسخ الخاص بك حيث يمكنك من خلال قائمة التضمين/الاستبعاد تحديد الخصائص التي تريد تحديدها أثناء النسخ العميق.هذه ممارسة شائعة جدًا عند إنشاء واجهات برمجة التطبيقات.

يمكنك اختيار عمل نسخة ضحلة فقط اذا أنت تفهم المخاطر التي تنطوي عليها.عندما يكون لديك عدد هائل من المؤشرات التي يتعين عليك التعامل معها في لغة C++ أو C، فإن عمل نسخة سطحية من الكائن يعد أمرًا عاديًا حقًا فكرة سيئة.

EXAMPLE_OF_DEEP نسخة_ على سبيل المثال، عندما تحاول إجراء معالجة الصور والتعرف على الكائنات، فإنك تحتاج إلى إخفاء "الحركة غير ذات الصلة والمتكررة" خارج مناطق المعالجة الخاصة بك.إذا كنت تستخدم مؤشرات الصور، فقد تكون لديك المواصفات اللازمة لحفظ صور الأقنعة هذه.الآن...إذا قمت بعمل نسخة ضحلة من الصورة، عندما يتم قتل مراجع المؤشر من المكدس، فقد فقدت المرجع ونسخته، أي.سيكون هناك خطأ في وقت التشغيل يتعلق بانتهاك الوصول في مرحلة ما.في هذه الحالة، ما تحتاجه هو نسخة عميقة من صورتك عن طريق استنساخها.وبهذه الطريقة يمكنك استرجاع الأقنعة في حالة احتياجك إليها في المستقبل.

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" إلى نفس الموقع في الذاكرة باسم 'المصدر' لا. نقاط "DeepCopy" إلى موقع آخر في الذاكرة، ولكن محتويات هي نفسها.

ما هي النسخة الضحلة؟

النسخة الضحلة هي نسخة بت من كائن ما.يتم إنشاء كائن جديد يحتوي على نسخة طبق الأصل من القيم الموجودة في الكائن الأصلي.إذا كان أي من حقول الكائن عبارة عن إشارات إلى كائنات أخرى، فسيتم نسخ العناوين المرجعية فقط، أي يتم نسخ عنوان الذاكرة فقط. Shallow Copy

في هذا الشكل، MainObject1 لديها حقول field1 من النوع int، و ContainObject1 من النوع ContainObject.عندما تقوم بعمل نسخة ضحلة من MainObject1, MainObject2 تم إنشاؤه مع field2 تحتوي على القيمة المنسوخة field1 وما زال يشير إلى ContainObject1 بحد ذاتها.لاحظ أنه منذ ذلك الحين field1 هو من النوع البدائي، ويتم نسخ قيمته إليه field2 لكن منذ ContainedObject1 هو كائن، MainObject2 لا يزال يشير إلى ContainObject1.لذلك أي تغييرات تم إجراؤها على ContainObject1 في MainObject1 سوف تنعكس في MainObject2.

الآن، إذا كانت هذه نسخة سطحية، فلنرى ما هي النسخة العميقة؟

ما هي النسخة العميقة؟

تقوم النسخة العميقة بنسخ كافة الحقول وإنشاء نسخ من الذاكرة المخصصة ديناميكيًا والتي تشير إليها الحقول.تحدث النسخة العميقة عندما يتم نسخ كائن مع الكائنات التي يشير إليها.Deep Copy

في هذا الشكل، يحتوي MainObject1 على حقول field1 من النوع int، و ContainObject1 من النوع ContainObject.عندما تقوم بعمل نسخة عميقة من MainObject1, MainObject2 تم إنشاؤه مع field2 تحتوي على القيمة المنسوخة field1 و ContainObject2 تحتوي على القيمة المنسوخة ContainObject1.لاحظ أي تغييرات تم إجراؤها على ContainObject1 في MainObject1 لن تنعكس في MainObject2.

مادة جيدة

في البرمجة وجوه المنحى، ويشمل نوع مجموعة من الحقول الأعضاء. قد يتم تخزين هذه الحقول سواء من حيث القيمة أو بالرجوع (أي مؤشر إلى القيمة).

في نسخة الضحلة، يتم إنشاء مثيل جديد من النوع ويتم نسخ القيم في مثيل جديد. يتم نسخ مؤشرات إشارة أيضا تماما مثل القيم. ولذلك، فإن الإشارات تشير إلى الكائنات الأصلية. تظهر أية تغييرات على الأعضاء التي يتم تخزينها من قبل المرجع في كل من الأصل والصورة، منذ أن تم إجراء أي نسخة من الكائن المشار إليه.

في نسخة عميق، يتم نسخ الحقول التي يتم تخزينها من حيث القيمة كما كان من قبل، ولكن لا يتم نسخ المؤشرات إلى الكائنات المخزنة حسب المرجع. بدلا من ذلك، يتم إجراء نسخة عميق من الكائن المشار إليه، ويتم تخزين مؤشر إلى كائن جديد. سوف أية تغييرات يتم إجراؤها على هذه الكائنات المشار إليها لن يؤثر على نسخ أخرى من وجوه.

ونقاط "ShallowCopy" إلى نفس الموقع في الذاكرة باسم 'المصدر' لا. نقاط "DeepCopy" إلى موقع آخر في الذاكرة، ولكن محتويات هي نفسها.

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

الاستنساخ الضحل:
تعريف:"نسخ نسخة ضحلة من كائن الكائن" الرئيسي "، ولكن لا ينسخ الكائنات الداخلية." عندما يكون كائن مخصص (على سبيل المثال.الموظف) يحتوي فقط على متغيرات بدائية من نوع السلسلة ثم تستخدم Shallow Cloning.

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");

ثم يتعين عليك كتابة الكود لاستنساخ كائن "العنوان" أيضًا في طريقة clone () التي تم تجاوزها.وإلا فلن يتم استنساخ كائن العنوان وسيسبب خطأ عند تغيير قيمة العنوان في كائن الموظف المستنسخ، والذي يعكس القيمة الأصلية أيضًا.

نسخة عميقة

تقوم النسخة العميقة بنسخ كافة الحقول وإنشاء نسخ من الذاكرة المخصصة ديناميكيًا والتي تشير إليها الحقول.تحدث النسخة العميقة عندما يتم نسخ كائن مع الكائنات التي يشير إليها.

نسخة سطحية

النسخة الضحلة هي نسخة بت من كائن ما.يتم إنشاء كائن جديد يحتوي على نسخة طبق الأصل من القيم الموجودة في الكائن الأصلي.إذا كان أي من حقول الكائن عبارة عن إشارات إلى كائنات أخرى، فسيتم نسخ العناوين المرجعية فقط، أي يتم نسخ عنوان الذاكرة فقط.

نسخة سطحية- المتغير المرجعي داخل الكائنات الأصلية والسطحية المنسوخة له إشارة إلى شائع هدف.

نسخة عميقة- المتغير المرجعي داخل الكائنات الأصلية والمنسوخة بعمق له إشارة إلى مختلف هدف.

يقوم الاستنساخ دائمًا بنسخ سطحي.

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());

انتاج- فيسوالباسيك ج

وأنا أود أن أعطي مثلا بدلا من تعريف رسمي.

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 !!
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);
}

في شروط بسيطة، نسخة الضحلة مشابه لدعوة المرجعية ونسخة ديب مشابه لدعوة من حيث القيمة

في نداء حسب المرجع، المعلمات على حد سواء الرسمية والفعلية وظيفة تشير إلى موقع الذاكرة نفس وقيمة.

في الدعوة من حيث القيمة والمعلمات على حد سواء الرسمية والفعلية من وظائف تشير إلى موقع ذاكرة مختلفة ولكن لها نفس القيمة.

وتخيل أن هناك دعا arr1 وarr2 اثنين من صفائف.

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

أجوف النسخ هو إنشاء كائن جديد ثم نسخ الحقول غير الثابتة للكائن الحالي إلى الكائن الجديد.إذا كان الحقل عبارة عن نوع قيمة --> يتم إجراء نسخة من الحقل خطوة بخطوة؛ل نوع مرجع --> تم نسخ المرجع ولكن الكائن المشار إليه ليس كذلك؛وبالتالي فإن الكائن الأصلي واستنساخه يشيران إلى نفس الكائن.

عميق تقوم النسخة بإنشاء كائن جديد ثم نسخ الحقول غير الثابتة للكائن الحالي إلى الكائن الجديد.إذا كان الحقل أ نوع القيمة --> يتم إجراء نسخة من الحقل شيئًا فشيئًا.إذا كان الحقل أ نوع مرجع --> يتم إجراء نسخة جديدة من الكائن المشار إليه.يجب وضع علامة على الفئات المراد استنساخها على أنها [قابلة للتسلسل].

مأخوذ من [مدونة]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

نسخة عميقة يتضمن استخدام محتويات كائن واحد لإنشاء مثيل آخر من نفس الفئة.في النسخة العميقة، قد يحتوي الكائنان على نفس المعلومات ولكن الكائن الهدف سيكون له مخازن مؤقتة وموارد خاصة به.لن يؤثر تدمير أي من الكائنين على الكائن المتبقي.سيقوم عامل التعيين المثقل بإنشاء نسخة عميقة من الكائنات.

نسخة سطحية يتضمن نسخ محتويات كائن واحد إلى مثيل آخر من نفس الفئة وبالتالي إنشاء صورة معكوسة.بسبب النسخ المباشر للمراجع والمؤشرات، سيتشارك الكائنان في نفس المحتويات الموجودة خارجيًا للكائن الآخر بحيث لا يمكن التنبؤ بها.

توضيح:

باستخدام مُنشئ النسخ، نقوم ببساطة بنسخ قيم البيانات عضوًا تلو الآخر.تسمى طريقة النسخ هذه بالنسخة الضحلة.إذا كان الكائن عبارة عن فئة بسيطة، تتألف من أنواع مضمنة ولا توجد مؤشرات، فسيكون هذا مقبولاً.ستستخدم هذه الوظيفة القيم والكائنات ولن يتم تغيير سلوكها بنسخة سطحية، حيث يتم نسخ عناوين المؤشرات الأعضاء فقط وليس القيمة التي يشير إليها العنوان.سيتم بعد ذلك تغيير قيم بيانات الكائن عن غير قصد بواسطة الوظيفة.عندما تخرج الوظيفة عن النطاق، يتم إخراج نسخة الكائن بكل بياناته من المكدس.

إذا كان الكائن يحتوي على أي مؤشرات، فيجب تنفيذ نسخة عميقة.باستخدام النسخة العميقة لكائن ما، يتم تخصيص الذاكرة للكائن الموجود في المتجر المجاني ويتم نسخ العناصر المشار إليها.يتم استخدام نسخة عميقة للكائنات التي يتم إرجاعها من دالة.

لإضافة المزيد إلى الإجابات الأخرى،

  • تقوم نسخة ضحلة من كائن بإجراء نسخة حسب القيمة لأنواع القيمة المستندة إلى الخصائص ، ونسخها حسب المرجع لخصائص الأنواع المرجعية القائمة.
  • تقوم نسخة عميقة من كائن بإجراء نسخة حسب القيمة لخصائص أنواع القيم ، وكذلك النسخ حسب القيمة لأنواع المرجعية المستندة إلى العمق في التسلسل الهرمي (من أنواع المراجع)

ونسخة الضحلة يبني كائن مركب جديد وإدراج اشارتها إلى أن الكائن الأصلي.

وعلى عكس نسخة الضحلة، deepcopy يبني الكائن المركب الجديد وأيضا إدراج نسخ من الكائنات الأصلية للكائن مركب الأصلي.

ويتيح نأخذ مثالا على ذلك.

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). ما الثعبان يفعل هنا، فإنه سيتم إنشاء كائن مركب جديد ولكن الأشياء داخلها تشير إلى الكائنات أصلي.

في الصورة التي خلقتها نسخة جديدة لقائمة الخارجية. لكن القائمة الداخلية لا تزال نفس الاصل واحد.

ونحن الآن إنشاء deepcopy منه باستخدام z = copy.deepcopy(x). ما الثعبان لا هنا، فإنه سيتم إنشاء كائن جديد لقائمة الخارجية وكذلك قائمة الداخلية. كما هو مبين في الصورة أدناه (الضوء الأحمر).

وفي False طباعة كود نهاية، وصاد وعين ليست الكائنات نفسها.

وHTH.

سوف

ونسخة الضحلة لا يخلق مرجعية جديدة ولكن نسخة عميق خلق مرجعية جديدة.

وهنا هو البرنامج لشرح نسخة العميقة والضحلة.

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 + "]";
    }
}

نسخ المصفوفات :

Array عبارة عن فئة ، مما يعني أنه نوع مرجعي لذلك 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]);
    }

استنساخ ضحل يعني أنه يتم نسخ الذاكرة التي يمثلها المصفوفة المستنسخة فقط.

إذا كان المصفوفة تحتوي على كائنات من نوع القيمة، فسيتم نسخ القيم;

إذا كان المصفوفة تحتوي على نوع مرجعي، فسيتم نسخ المراجع فقط - ونتيجة لذلك يكون هناك مصفوفتان يشير أعضاؤهما إلى نفس الكائنات.

لإنشاء نسخة عميقة - حيث يتم تكرار نوع المرجع، يجب عليك التكرار خلال المصفوفة واستنساخ كل عنصر يدويًا.

وإضافة إلى كل التعاريف المذكورة أعلاه، واحد اكثر والأكثر شيوعا نسخة عميق، في منشئ نسخة (أو إثقال oprator الاحالة) للفئة.

ونسخة الضحلة -> هو عند عدم توفر نسخة منشئ. هنا، فقط الكائن يحصل على نسخ ولكن يتم نسخ ليس كل أفراد الطبقة.

ونسخة العميقة -> عندما كنت قد قررت تنفيذ نسخة منشئ أو التنازل الزائد في صفك ويسمح نسخ كافة أفراد الطبقة

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 ++ الصانعين .

لإضافة أكثر قليلا عن الخلط بين نسخة الضحلة وببساطة تعيين اسم متغير جديد إلى القائمة.

و"قل لدينا:

x = [
    [1,2,3],
    [4,5,6],
    ]

وهذا البيان يخلق 3 قوائم: 2 القوائم الداخلية والخارجية قائمة واحدة. يتم إجراء إشارة إلى القائمة الخارجية ثم متوفرة تحت اسم السينية. اذا لم نفعل

y = x

ويحصل على نسخ أية بيانات. لا يزال لدينا نفس 3 قوائم في الذاكرة في مكان ما. كل هذا لم هو جعل القائمة الخارجية المتوفرة تحت اسم ذ، بالإضافة إلى اسمها س السابق. اذا لم نفعل

y = list(x)

أو

y = x[:]

وهذا يخلق قائمة جديدة مع نفس المحتويات كما السينية. قائمة العاشر يتضمن إشارة إلى القوائم الداخلية 2، وبالتالي فإن القائمة الجديدة ستحتوي أيضا إشارة إلى نفس تلك القوائم 2 الداخلية. والقائمة الخارجية للنسخ-قائمة واحدة فقط. الآن هناك 4 قوائم في الذاكرة، واثنين من القوائم الداخلية، والخارجية القائمة، ونسخة من قائمة الخارجية. قائمة الخارجية الأصلية المتاحة تحت اسم س، ويرصد قائمة الخارجية الجديدة متوفرة تحت اسم ذ.

ولم يتم نسخ القوائم الداخلية! يمكنك الوصول إلى وتعديل القوائم الداخلية من أي x أو y في هذه النقطة!

إذا كان لديك الأبعاد (أو أعلى) القائمة اثنين، أو أي نوع من بنية بيانات متداخلة، وأنت تريد أن تجعل من نسخة كاملة من كل شيء، فإنك ترغب في استخدام وظيفة deepcopy () في وحدة نسخة. يعمل الحل أيضا لقوائم 2-D، كما بالتكرار عبر العناصر في قائمة الخارجية ويجعل نسخة من كل منهم، ثم يبني على قائمة الخارجية الجديدة لجميع النسخ الداخلية. "

المصدر: https://www.reddit.com/r/ learnpython / تعليقات / 1afldr / why_is_copying_a_list_so_damn_difficult_in_python /

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top