Дослідимо різницю між конструктором копіювання та оператором присвоювання.
Діаграма порівняння
Основа для порівняння | Копіювати конструктор | Оператор призначення |
---|---|---|
Основний | Конструктор копіювання - це перевантажений конструктор. | Оператор присвоювання є побітовим оператором. |
Значення | Конструктор копіювання ініціалізує новий об'єкт з вже існуючим об'єктом. | Оператор присвоєння призначає значення одного об'єкта іншому об'єкту, обидва з яких вже існують. |
Синтаксис | class_name (cont class_name & object_name) { // тіло конструктора } | class_name Ob1, Ob2; Ob2 = Ob1; |
Викликає | (1) Конструктор копіювання викликає, коли новий об'єкт ініціалізується з існуючим. (2) Об'єкт передається функції як нереференційний параметр. (3) Об'єкт повертається з функції. | Оператор присвоєння викликається тільки при призначенні існуючого об'єкта новим об'єктом. |
Виділення пам'яті | І цільовий об'єкт, і об'єкт ініціалізації спільно використовують різні місця пам'яті. | І цільовий об'єкт, і ініціалізує об'єкт поділяють ту ж виділену пам'ять. |
За замовчуванням | Якщо ви не визначите будь-який конструктор копіювання в програмі, компілятор C ++ неявно надає його. | Якщо ви не перевантажуєте оператора "=", то виконується побітова копія. |
Визначення конструктора копіювання
"Конструктор копіювання" є формою перевантаженого конструктора . Конструктор копіювання викликається або викликається тільки для цілей ініціалізації. Конструктор копіювання ініціалізує новостворений об'єкт іншим існуючим об'єктом. Коли конструктор копіювання використовується для ініціалізації новоствореного цільового об'єкта, то і цільовий об'єкт, і вихідний об'єкт розділяють інше розташування пам'яті. Зміни, виконані у вихідному об'єкті, не відображаються в цільовому об'єкті. Загальною формою конструктора копіювання є
ім'я class_ (ім'я класу & ім'я об'єкта) {. // тіло конструктора копіювання. } // object_name відноситься до об'єкта в правій частині ініціалізації.
Якщо програміст не створює конструктор копіювання в програмі C ++, то компілятор неявно надає конструктор копіювання. Конструктор неявних копій, наданий компілятором, виконує член-копію вихідного об'єкта. Але, іноді член-мудрі копії не достатньо, так як об'єкт може містити покажчик змінної. Копіюючи вказівник змінної, ми копіюємо адресу, що зберігається в покажчику, але ми не хочемо копіювати адресу, що зберігається у змінній покажчика, замість того, щоб скопіювати на що вказує покажчик. Отже, у програмі необхідний явний «конструктор копіювання» для вирішення такого роду проблем.
Конструктор копіювання викликається в трьох наступних умовах:
- Конструктор копіювання викликає, коли новий об'єкт ініціалізується з існуючим.
- Об'єкт передається функції як нереференційний параметр.
- Об'єкт повертається з функції.
Давайте зрозуміємо конструктор копіювання з прикладом.
копія класу {int num; public: copy () {} // копія конструктора за замовчуванням (int a) {// ініціалізація конструктора num = a; } копіювати (копіювати & c) {// Копіювати конструктор num = c.num; } void show () {cout << num; }}; int main () {copy A (200); // Об'єкт A створений і ініціалізований копію B (A); // Копіювати конструктор копією C = A; // Копіювати конструктор копією D; D = A; // копіювати конструктор не викликається тому, що об'єкт D не новостворений об'єкт. // це операція призначення. return 0; }
У наведеному вище коді я явно оголосив конструктор "копіювати (копіювати & c)". Цей конструктор копіювання викликається, коли об'єкт B ініціалізується за допомогою об'єкта А. Другий раз він викликається, коли об'єкт C ініціалізується за допомогою об'єкта А. Коли об'єкт D ініціалізується за допомогою об'єкта A, конструктор копіювання не викликається, оскільки при ініціалізації D це вже в існуванні, а не в новоствореному. Отже, тут викликається оператор присвоєння.
Визначення оператора призначення
Оператор присвоєння є оператором призначення C ++. Оператор "=" використовується для виклику оператора присвоєння. Він копіює дані в одному об'єкті однаково до іншого об'єкта. Оператор присвоювання копіює один об'єкт іншому члену. Якщо ви не перевантажуєте оператор присвоєння, він виконує бітову копію. Тому потрібно перевантажити оператор присвоєння.
копія класу {int num; public: copy () {} // копія конструктора за замовчуванням (int a) {// ініціалізація конструктора num = a; } void show () {cout << num; }}; int main () {copy A (200); // Об'єкт A створений і ініціалізований копією B (300); // Об'єкт B створений і ініціалізований B = A; // оператор присвоєння викликається копією C; C = A; // оператор присвоєння викликається return 0; }
У вищевказаному коді, коли objectA присвоюється об'єкту B, оператор присвоєння викликається, оскільки обидва об'єкти вже існують. Аналогічно, те ж саме відбувається, коли об'єкт С ініціалізується об'єктом А. \ t
Коли виконується побітове присвоєння, об'єкт поділяє одне і те ж розташування пам'яті, а зміни в одному об'єкті відображають в іншому об'єкті.
Основні відмінності між конструктором копіювання та оператором призначення
- Конструктор копіювання є перевантаженим конструктором, де як оператор присвоєння є побітовим оператором.
- Використовуючи конструктор копіювання, можна ініціалізувати новий об'єкт з вже існуючим об'єктом. З іншого боку, оператор присвоєння копіює один об'єкт на інший об'єкт, який вже існує.
- Конструктор копіювання ініціалізується всякий раз, коли новий об'єкт ініціалізується з вже існуючим об'єктом, коли об'єкт передається функції як параметр, що не рефренсується, або коли об'єкт повертається з функції. З іншого боку, оператор присвоєння викликається тільки тоді, коли об'єкт призначається іншому об'єкту.
- Коли об'єкт ініціалізується за допомогою конструктора копіювання, об'єкт ініціалізації та ініціалізований об'єкт спільно використовують інше розташування пам'яті. З іншого боку, коли об'єкт ініціалізується за допомогою оператора присвоєння, ініціалізовані та ініціалізуються об'єкти розділяють одне і те ж місце пам'яті.
- Якщо ви явно не визначите конструктор копіювання, компілятор надасть його. З іншого боку, якщо ви не перевантажуєте оператора assigment, то виконується операція побітового копіювання.
Висновок:
Конструктор копіювання найкращий для копіювання одного об'єкта в інший, коли об'єкт містить необроблені покажчики.