Un constructor Copy este un supraîncărcat constructor folosit pentru a declara și inițializa un obiect dintr-un alt obiect.
Copy Constructor este de două tipuri:
Sintaxa constructorului de copiere definit de utilizator:
Class_name(const class_name &old_object);
Luați în considerare următoarea situație:
java 8
class A { A(A &x) // copy constructor. { // copyconstructor. } }
În cazul de mai sus, constructorul de copiere poate fi apelat în următoarele moduri:
Să vedem un exemplu simplu de constructor de copiere.
// programul constructorului de copiere.
#include using namespace std; class A { public: int x; A(int a) // parameterized constructor. { x=a; } A(A &i) // copy constructor { x = i.x; } }; int main() { A a1(20); // Calling the parameterized constructor. A a2(a1); // Calling the copy constructor. cout< <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'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 << 'value of a is : ' < <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'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 &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 << 'value of a is : ' < <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 &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 '=' operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<></pre></a<<></pre></a2.x;>
Când este apelat Copy Constructor
Copy Constructor este apelat în următoarele scenarii:
- Când inițializam obiectul cu un alt obiect existent de același tip de clasă. De exemplu, Student s1 = s2, unde Student este clasa.
- Când obiectul aceluiași tip de clasă este transmis prin valoare ca argument.
- Când funcția returnează obiectul aceluiași tip de clasă după valoare.
Două tipuri de copii sunt produse de constructor:
- Copie superficială
- Copie adâncă
Copie superficială
- Constructorul de copiere implicit poate produce doar copia superficială.
- O copie superficială este definită ca procesul de creare a copiei unui obiect prin copierea datelor tuturor variabilelor membre așa cum sunt.
Să înțelegem asta printr-un exemplu simplu:
sunny deol age
#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 << 'value of a is : ' < <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'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 &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 << 'value of a is : ' < <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 &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 '=' operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<></pre></a<<>
În cazul de mai sus, un programator nu a definit niciun constructor, prin urmare, instrucțiunea Demo d2 = d1; apelează constructorul implicit definit de compilator. Constructorul implicit creează copia exactă sau copia superficială a obiectului existent. Astfel, indicatorul p al ambelor obiecte indică aceeași locație de memorie. Prin urmare, atunci când memoria unui câmp este eliberată, memoria altui câmp este de asemenea eliberată automat, deoarece ambele câmpuri indică aceeași locație de memorie. Această problemă este rezolvată de constructor definit de utilizator care creează Copie adâncă .
Copie adâncă
Deep copy alocă dinamic memoria pentru copiere și apoi copiază valoarea reală, atât sursa, cât și copia au locații de memorie distincte. În acest fel, atât sursa, cât și copia sunt distincte și nu vor partaja aceeași locație de memorie. Copierea profundă necesită să scriem constructorul definit de utilizator.
Să înțelegem asta printr-un exemplu simplu.
#include using namespace std; class Demo { public: int a; int b; int *p; Demo() { p=new int; } Demo(Demo &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 << 'value of a is : ' < <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 &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 '=' operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<>
În cazul de mai sus, un programator și-a definit propriul constructor, deci instrucțiunea Demo d2 = d1; apelează constructorul de copiere definit de utilizator. Acesta creează copia exactă a datelor tipului de valoare și a obiectului indicat de indicatorul p. Deep copy nu creează copia unei variabile de tip referință.
Diferențele b/n Copy constructor și Assignment operator(=)
Copie constructor | Operator de atribuire |
---|---|
Este un constructor supraîncărcat. | Este un operator pe biți. |
Inițializează noul obiect cu obiectul existent. | Acesta atribuie valoarea unui obiect altui obiect. |
Sintaxa constructorului de copiere: Class_name(const class_name &object_name) { // corpul constructorului. } | Sintaxa operatorului de atribuire: Nume_clasa a,b; b = a; |
| The operator de atribuire este invocat atunci când atribuim obiectul existent unui obiect nou. |
Atât obiectul existent, cât și noul obiect partajează diferite locații de memorie. | Atât obiectul existent, cât și noul obiect partajează aceeași locație de memorie. |
Dacă un programator nu definește constructorul de copiere, compilatorul va genera automat constructorul implicit implicit de copiere. | Dacă nu supraîncărcăm operatorul „=”, va avea loc copia pe biți. |