►Мелкое копирование — глубокие проблемы...272

Независимо от того, что думаете вы и многие другие о переопределении операторов, вам всё равно придётся переопределять оператор присвоения для множества ваших классов. С++ предоставляет определение operator=( ) по умолчанию, но этот оператор просто выполняет почленное копирование. Такое присвоение отлично работает для встроенных операторов типа int.

        int i ;

        i = 10 ;

Точно так же ведёт себя присвоение по умолчанию и для пользовательских классов. В следующем примере каждый член source копируется в соответствующий член destination.

        void fn( )

        {

        MyStruct source , destination ;

        destination = source ;

        }

Оператор присвоения по умолчанию вполне работоспособен для большинства классов, однако при выделении ресурсов, таких как память из кучи, начинаются проблемы. В этом случае программист должен переопределить оператор operator=( ) для корректной передачи ресурса.

Оператор присвоения очень похож на конструктор копирования, а при использовании они практически идентичны.

    void fn( MyClass& mc )

    {

        MyClass newMC( mc ) ; /* Здесь используется конструктор копирования */

        MyClass newerMC = mc ; /* Менее очевидно, что здесь также используется конструктор копирования */

        MyClass newestMC ; /* Создание объекта по умолчанию */

        newestMC = mc ; /* Присвоение */

    }

_________________

272 стр. Часть 5. Полезные особенности

Создание newMC следует стандартному шаблону создания нового объекта как зеркального отображения существующего с использованием копирующего конструктора MyClass( MyClass& ). Несколько менее очевидно, что объект newerMC также создаётся при помощи конструктора копирования. Запись MyClass а = b — всего лишь другой способ записи MyClass a( b ). То, что в первом варианте записи имеется символ "=", не приводит к вызову оператора присвоения. Однако в случае с объектом newestMC всё не совсем так. Сначала этот объект создаётся с использованием конструктора по умолчанию, а затем перезаписывается объектом mc с помощью оператора присвоения.

Подобно конструктору копирования, оператор присвоения должен быть переопределён, если мелкое копирование приводит к некорректным результатам ( см. материал, представленный в главе 18, "Копирующий конструктор" ). Простейшее правило: если у класса есть пользовательский конструктор копирования, то переопределите для него и оператор присвоения.

«Главное правило заключается в следующем: конструктор копирования используется при создании нового объекта, а оператор присвоения — если объект слева от символа присвоения уже существует.»

[Советы]