logo

منشئ نسخ C++

منشئ النسخ هو مثقلة المُنشئ المستخدم للإعلان عن كائن وتهيئته من كائن آخر.

منشئ النسخ هو من نوعين:

    منشئ النسخ الافتراضي:يحدد المترجم منشئ النسخ الافتراضي. إذا لم يحدد المستخدم مُنشئ نسخة، فإن المترجم يوفر المُنشئ الخاص به.منشئ محدد من قبل المستخدم:يحدد المبرمج المنشئ المحدد من قبل المستخدم.
منشئ نسخ C++

بناء جملة مُنشئ النسخ المحدد من قبل المستخدم:

 Class_name(const class_name &old_object); 

خذ بعين الاعتبار الحالة التالية:

ج مجموعة سلسلة البرنامج
 class A { A(A &x) // copy constructor. { // copyconstructor. } } 

في الحالة المذكورة أعلاه، يمكن استدعاء مُنشئ النسخ بالطرق التالية:

منشئ نسخ C++

دعونا نرى مثالاً بسيطًا لمنشئ النسخ.

// برنامج منشئ النسخ.

 #include using namespace std; class A { public: int x; A(int a) // parameterized constructor. { x=a; } A(A &amp;i) // copy constructor { x = i.x; } }; int main() { A a1(20); // Calling the parameterized constructor. A a2(a1); // Calling the copy constructor. cout&lt; <a2.x; return 0; } < pre> <p> <strong>Output:</strong> </p> <pre> 20 </pre> <h2>When Copy Constructor is called</h2> <p>Copy Constructor is called in the following scenarios:</p> <ul> <li>When we initialize the object with another existing object of the same class type. For example, Student s1 = s2, where Student is the class.</li> <li>When the object of the same class type is passed by value as an argument.</li> <li>When the function returns the object of the same class type by value.</li> </ul> <h2>Two types of copies are produced by the constructor:</h2> <ul> <li>Shallow copy</li> <li>Deep copy</li> </ul> <h2>Shallow Copy</h2> <ul> <li>The default copy constructor can only produce the shallow copy.</li> <li>A Shallow copy is defined as the process of creating the copy of an object by copying data of all the member variables as it is.</li> </ul> <p>Let&apos;s understand this through a simple example:</p> <pre> #include using namespace std; class Demo { int a; int b; int *p; public: Demo() { p=new int; } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << 'value of b is : ' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-3.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has not defined any constructor, therefore, the statement <strong>Demo d2 = d1;</strong> calls the default constructor defined by the compiler. The default constructor creates the exact copy or shallow copy of the existing object. Thus, the pointer p of both the objects point to the same memory location. Therefore, when the memory of a field is freed, the memory of another field is also automatically freed as both the fields point to the same memory location. This problem is solved by the <strong>user-defined constructor</strong> that creates the <strong>Deep copy</strong> .</p> <h2>Deep copy</h2> <p>Deep copy dynamically allocates the memory for the copy and then copies the actual value, both the source and copy have distinct memory locations. In this way, both the source and copy are distinct and will not share the same memory location. Deep copy requires us to write the user-defined constructor.</p> <p>Let&apos;s understand this through a simple example.</p> <pre> #include using namespace std; class Demo { public: int a; int b; int *p; Demo() { p=new int; } Demo(Demo &amp;d) { a = d.a; b = d.b; p = new int; *p = *(d.p); } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << 'value of b is : ' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-4.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has defined its own constructor, therefore the statement <strong>Demo d2 = d1;</strong> calls the copy constructor defined by the user. It creates the exact copy of the value types data and the object pointed by the pointer p. Deep copy does not create the copy of a reference type variable.</p> <h2>Differences b/w Copy constructor and Assignment operator(=)</h2> <table class="table"> <tr> <th>Copy Constructor</th> <th>Assignment Operator</th> </tr> <tr> <td>It is an overloaded constructor.</td> <td>It is a bitwise operator.</td> </tr> <tr> <td>It initializes the new object with the existing object.</td> <td>It assigns the value of one object to another object.</td> </tr> <tr> <td>Syntax of copy constructor: <br> Class_name(const class_name &amp;object_name) <br> { <br> // body of the constructor. <br> }</td> <td>Syntax of Assignment operator: <br> Class_name a,b; <br> b = a;</td> </tr> <tr> <td><ul> <li>The <strong>copy constructor</strong> is invoked when the new object is initialized with the existing object.</li> <li>The object is passed as an argument to the function.</li> <li>It returns the object.</li> </ul></td> <td>The <strong>assignment operator</strong> is invoked when we assign the existing object to a new object.</td> </tr> <tr> <td>Both the existing object and new object shares the different memory locations.</td> <td>Both the existing object and new object shares the same memory location.</td> </tr> <tr> <td>If a programmer does not define the copy constructor, the compiler will automatically generate the implicit default copy constructor. </td> <td>If we do not overload the &apos;=&apos; operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<></pre></a<<></pre></a2.x;>

عندما يتم استدعاء منشئ النسخ

يتم استدعاء Copy Constructor في السيناريوهات التالية:

افعل ذلك أثناء تواجدك في Java
  • عندما نقوم بتهيئة الكائن بكائن آخر موجود من نفس نوع الفئة. على سبيل المثال، الطالب s1 = s2، حيث الطالب هو الفصل الدراسي.
  • عندما يتم تمرير كائن من نفس نوع الفئة بالقيمة كوسيطة.
  • عندما تقوم الدالة بإرجاع كائن من نفس نوع الفئة حسب القيمة.

يتم إنتاج نوعين من النسخ بواسطة المنشئ:

  • نسخة سطحية
  • نسخة عميقة

نسخة سطحية

  • يمكن لمنشئ النسخ الافتراضي إنتاج النسخة السطحية فقط.
  • يتم تعريف النسخة الضحلة على أنها عملية إنشاء نسخة من كائن عن طريق نسخ بيانات جميع متغيرات الأعضاء كما هي.

دعونا نفهم ذلك من خلال مثال بسيط:

 #include using namespace std; class Demo { int a; int b; int *p; public: Demo() { p=new int; } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << \'value of b is : \' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-3.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has not defined any constructor, therefore, the statement <strong>Demo d2 = d1;</strong> calls the default constructor defined by the compiler. The default constructor creates the exact copy or shallow copy of the existing object. Thus, the pointer p of both the objects point to the same memory location. Therefore, when the memory of a field is freed, the memory of another field is also automatically freed as both the fields point to the same memory location. This problem is solved by the <strong>user-defined constructor</strong> that creates the <strong>Deep copy</strong> .</p> <h2>Deep copy</h2> <p>Deep copy dynamically allocates the memory for the copy and then copies the actual value, both the source and copy have distinct memory locations. In this way, both the source and copy are distinct and will not share the same memory location. Deep copy requires us to write the user-defined constructor.</p> <p>Let&apos;s understand this through a simple example.</p> <pre> #include using namespace std; class Demo { public: int a; int b; int *p; Demo() { p=new int; } Demo(Demo &amp;d) { a = d.a; b = d.b; p = new int; *p = *(d.p); } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << \'value of b is : \' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-4.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has defined its own constructor, therefore the statement <strong>Demo d2 = d1;</strong> calls the copy constructor defined by the user. It creates the exact copy of the value types data and the object pointed by the pointer p. Deep copy does not create the copy of a reference type variable.</p> <h2>Differences b/w Copy constructor and Assignment operator(=)</h2> <table class="table"> <tr> <th>Copy Constructor</th> <th>Assignment Operator</th> </tr> <tr> <td>It is an overloaded constructor.</td> <td>It is a bitwise operator.</td> </tr> <tr> <td>It initializes the new object with the existing object.</td> <td>It assigns the value of one object to another object.</td> </tr> <tr> <td>Syntax of copy constructor: <br> Class_name(const class_name &amp;object_name) <br> { <br> // body of the constructor. <br> }</td> <td>Syntax of Assignment operator: <br> Class_name a,b; <br> b = a;</td> </tr> <tr> <td><ul> <li>The <strong>copy constructor</strong> is invoked when the new object is initialized with the existing object.</li> <li>The object is passed as an argument to the function.</li> <li>It returns the object.</li> </ul></td> <td>The <strong>assignment operator</strong> is invoked when we assign the existing object to a new object.</td> </tr> <tr> <td>Both the existing object and new object shares the different memory locations.</td> <td>Both the existing object and new object shares the same memory location.</td> </tr> <tr> <td>If a programmer does not define the copy constructor, the compiler will automatically generate the implicit default copy constructor. </td> <td>If we do not overload the &apos;=&apos; operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<></pre></a<<>
منشئ نسخ C++

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

نسخة عميقة

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

دعونا نفهم هذا من خلال مثال بسيط.

 #include using namespace std; class Demo { public: int a; int b; int *p; Demo() { p=new int; } Demo(Demo &amp;d) { a = d.a; b = d.b; p = new int; *p = *(d.p); } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << \'value of b is : \' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-4.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has defined its own constructor, therefore the statement <strong>Demo d2 = d1;</strong> calls the copy constructor defined by the user. It creates the exact copy of the value types data and the object pointed by the pointer p. Deep copy does not create the copy of a reference type variable.</p> <h2>Differences b/w Copy constructor and Assignment operator(=)</h2> <table class="table"> <tr> <th>Copy Constructor</th> <th>Assignment Operator</th> </tr> <tr> <td>It is an overloaded constructor.</td> <td>It is a bitwise operator.</td> </tr> <tr> <td>It initializes the new object with the existing object.</td> <td>It assigns the value of one object to another object.</td> </tr> <tr> <td>Syntax of copy constructor: <br> Class_name(const class_name &amp;object_name) <br> { <br> // body of the constructor. <br> }</td> <td>Syntax of Assignment operator: <br> Class_name a,b; <br> b = a;</td> </tr> <tr> <td><ul> <li>The <strong>copy constructor</strong> is invoked when the new object is initialized with the existing object.</li> <li>The object is passed as an argument to the function.</li> <li>It returns the object.</li> </ul></td> <td>The <strong>assignment operator</strong> is invoked when we assign the existing object to a new object.</td> </tr> <tr> <td>Both the existing object and new object shares the different memory locations.</td> <td>Both the existing object and new object shares the same memory location.</td> </tr> <tr> <td>If a programmer does not define the copy constructor, the compiler will automatically generate the implicit default copy constructor. </td> <td>If we do not overload the &apos;=&apos; operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<>
منشئ نسخ C++

في الحالة المذكورة أعلاه، قام المبرمج بتعريف المُنشئ الخاص به، وبالتالي البيان Demo d2 = d1; يستدعي منشئ النسخ المحدد من قبل المستخدم. يقوم بإنشاء النسخة الدقيقة من بيانات أنواع القيمة والكائن الذي يشير إليه المؤشر p. لا تؤدي النسخة العميقة إلى إنشاء نسخة لمتغير النوع المرجعي.

الاختلافات b/w مُنشئ النسخ ومشغل التعيين(=)

نسخ المنشئ مهمة تشغيل
وهو منشئ مثقلة. وهو عامل bitwise.
يقوم بتهيئة الكائن الجديد بالكائن الموجود. يقوم بتعيين قيمة كائن واحد لكائن آخر.
بناء جملة منشئ النسخ:
Class_name(const class_name &object_name)
{
// جسم المنشئ.
}
بناء جملة عامل التعيين:
Class_name أ، ب؛
ب = أ؛
  • ال منشئ النسخ يتم استدعاؤه عند تهيئة الكائن الجديد بالكائن الموجود.
  • يتم تمرير الكائن كوسيطة للوظيفة.
  • يقوم بإرجاع الكائن.
ال مهمة تشغيل يتم استدعاؤه عندما نقوم بتعيين كائن موجود لكائن جديد.
يشترك كل من الكائن الموجود والكائن الجديد في مواقع الذاكرة المختلفة. يشترك كل من الكائن الموجود والكائن الجديد في نفس موقع الذاكرة.
إذا لم يقم المبرمج بتعريف مُنشئ النسخة، فسيقوم المترجم تلقائيًا بإنشاء مُنشئ النسخة الافتراضية الضمنية. إذا لم نقم بتحميل عامل التشغيل '=' بشكل زائد، فسيتم إجراء النسخ بالبت.