Глава 17. Конструкторы: копирование и присваивание_________________405

Работа конструктора копий — создание ранее не существовавшего объекта из существующего, а передача по значению (без использования операции получения адреса) требует создания копии аргумента, значит мы получаем бесконечную рекурсию. Точнее: при передаче объекта по значению создается его копия; если это произойдет в конструкторе копий, то он будет вызывать сам себя, пока не исчерпает все ресурсы.

Вот несколько правил, которым надо следовать при объявлениях конструктора копий:

• Имя функции точно совпадает с именем класса.

• Аргумент объявляется постоянным, что позволяет принимать как постоянные, так и переменные аргументы.

• Тип аргумента является типом класса.

• Аргумент передается по ссылке, т. е. с помощью операции получения адреса.

Начиная определять новый класс, сразу же пишите конструктор копий, чтобы потом не забыть о нем.

Определение операции присваивания

По функциональному назначению операция присваивания похожа на конструктор копий. Отличие состоит в том, что конструктор копий создает новый (возможно, временный) объект, а операция присваивания работает с уже созданными. Вызывающий объект является левым операндом, объект-аргумент — правым.

Операция присваивания также имеет соответствующий синтаксис. Операция присваивания ~ это функция-член и одновременно двухместная операция. Следовательно (см. главу 16 "Перегрузка операций"), в работу вовлечены два объекта. Первый объект — вызывающий, доступный по указателю this, а второй — это аргумент. Как конструктор копий, так и операция присваивания используют как аргумент постоянную ссылку. Для произвольного класса х мы имеем следующий синтаксис операции присваивания:

Х& operator"(const X&); // синтаксис операции присваивания // для произвольного класса

Присваивание — это операция, значит мы должны использовать ключевое слово operator и соответствующий символ операции. Так как C++ допускает цепочки присваивания

а = Ь = с = d; // C++ допускает последовательные присваивания, // так что это свойство надо сохранить

то необходимо возвращать ссылку на объект; в противном случае цепочка прервется. Итак, оператор-функция принимает постоянную ссылку, а возвращает ссылку на объект.