Чем отличается конструктор копирования от оператора присваивания?cplus-87

Основное концептуальное отличие

Конструктор копирования создает новый объект как копию существующего, тогда как оператор присваивания модифицирует уже существующий объект, заменяя его содержимое копией другого объекта.

Синтаксическая разница

class Example {
public:
    // Конструктор копирования
    Example(const Example& other);
    
    // Оператор присваивания
    Example& operator=(const Example& other);
};

Ключевые различия

ХарактеристикаКонструктор копированияОператор присваивания
Когда вызываетсяПри создании нового объектаПри присваивании существующему объекту
Возвращаемое значениеНет (не возвращает ничего)Возвращает ссылку на объект (*this)
Инициализация членовИнициализирует все членыЗаменяет значения существующих членов
Проверка самоприсваиванияНе требуетсяОбязательна

Примеры вызова

Example a;          // Обычный конструктор
Example b(a);       // Конструктор копирования
Example c = a;      // Тоже конструктор копирования
b = c;              // Оператор присваивания

Особенности реализации

1. Конструктор копирования

Example::Example(const Example& other) 
    : member1(other.member1), member2(other.member2) {
    // Инициализация нового объекта
}

2. Оператор присваивания

Example& Example::operator=(const Example& other) {
    if (this != &other) {  // Проверка самоприсваивания
        member1 = other.member1;
        member2 = other.member2;
    }
    return *this;  // Возвращаем ссылку на текущий объект
}

Глубокая копия vs поверхностная копия

Оба метода должны учитывать:

  • Для простых типов - копирование значений
  • Для динамической памяти - глубокая копия (создание новых ресурсов)
  • Для указателей - либо копирование значения указателя, либо копирование данных

Идиома Copy-and-Swap

Продвинутый способ реализации оператора присваивания:

Example& Example::operator=(Example other) {  // Параметр по значению
    swap(*this, other);  // Обмен содержимым
    return *this;        // other уничтожится с старыми данными
}

Особые случаи

  1. Конструктор перемещения и оператор перемещающего присваивания (C++11+)
  2. Правило трех/пяти/нуля
  3. Исключения - оператор присваивания должен обеспечивать строгую гарантию исключений

Резюмируем

Основные различия:

  1. Конструктор копирования создает новый объект, оператор присваивания модифицирует существующий
  2. Конструктор инициализирует члены, оператор заменяет их значения
  3. Оператор присваивания должен проверять самоприсваивание и возвращать *this
  4. Оба должны корректно обрабатывать глубокое копирование ресурсов

Правильная реализация обоих методов критически важна для безопасной работы с классами, управляющими ресурсами.