Конструктор копіювання є перевантажений конструктор, який використовується для оголошення та ініціалізації об’єкта з іншого об’єкта.
Конструктор копіювання буває двох типів:
Синтаксис конструктора копіювання, визначеного користувачем:
Class_name(const class_name &old_object);
Розглянемо таку ситуацію:
щось швидке сортування
class A { A(A &x) // copy constructor. { // copyconstructor. } }
У наведеному вище випадку конструктор копіювання можна викликати такими способами:
Давайте розглянемо простий приклад конструктора копіювання.
// програма конструктора копії.
#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;>
Коли викликається Конструктор копіювання
Конструктор копіювання викликається в таких сценаріях:
- Коли ми ініціалізуємо об’єкт іншим існуючим об’єктом того самого типу класу. Наприклад, Student s1 = s2, де Student є класом.
- Коли об’єкт того самого типу класу передається за значенням як аргумент.
- Коли функція повертає об’єкт того самого типу класу за значенням.
Конструктор створює два типи копій:
- Неглибока копія
- Глибока копія
Неглибока копія
- Конструктор копіювання за замовчуванням може створити лише поверхневу копію.
- Неглибока копія визначається як процес створення копії об’єкта шляхом копіювання даних усіх змінних-членів як вони є.
Давайте зрозуміємо це на простому прикладі:
#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<<>
У наведеному вище випадку програміст не визначив жодного конструктора, отже, оператора Демо d2 = d1; викликає конструктор за замовчуванням, визначений компілятором. Конструктор за замовчуванням створює точну копію або поверхневу копію існуючого об’єкта. Таким чином, вказівник p обох об’єктів вказує на одне й те саме місце пам’яті. Таким чином, коли пам’ять поля звільняється, пам’ять іншого поля також автоматично звільняється, оскільки обидва поля вказують на ту саму область пам’яті. Цю проблему вирішує визначений користувачем конструктор що створює Глибока копія .
javascript для спадного меню
Глибока копія
Глибоке копіювання динамічно виділяє пам’ять для копії, а потім копіює фактичне значення, і джерело, і копія мають різні місця пам’яті. Таким чином, і джерело, і копія є різними і не використовуватимуть одне й те саме місце в пам’яті. Глибоке копіювання вимагає від нас написання визначеного користувачем конструктора.
Давайте зрозуміємо це на простому прикладі.
#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<<>
У наведеному вище випадку програміст визначив власний конструктор, отже, оператор Демо d2 = d1; викликає конструктор копіювання, визначений користувачем. Він створює точну копію даних типів значень і об’єкта, на який вказує вказівник p. Глибока копія не створює копію змінної посилального типу.
Відмінності ч/б Конструктор копіювання та оператор присвоєння (=)
Конструктор копіювання | Оператор присвоєння |
---|---|
Це перевантажений конструктор. | Це побітовий оператор. |
Він ініціалізує новий об’єкт наявним об’єктом. | Він присвоює значення одного об’єкта іншому об’єкту. |
Синтаксис конструктора копіювання: Class_name(const class_name &object_name) { // тіло конструктора. } | Синтаксис оператора присвоєння: Назва_класу a,b; b = a; |
| The оператор присвоєння викликається, коли ми призначаємо існуючий об’єкт новому об’єкту. |
І існуючий об’єкт, і новий об’єкт спільно використовують різні місця пам’яті. | Як існуючий об’єкт, так і новий об’єкт спільно використовують те саме місце пам’яті. |
Якщо програміст не визначає конструктор копіювання, компілятор автоматично згенерує неявний конструктор копіювання за замовчуванням. | Якщо ми не перевантажимо оператор =, відбудеться порозрядне копіювання. |