Глава 17. Конструкторы: копирование и присваивание 407
образом, сравниваются два адреса. Если они эквивалентны ( ==), то это один и тот же объект. В этом случае в полном соответствии с требованием возврата ссылки на объект возвращаем *this (заметьте, что в конце функции делается то же самое) и выходим из функции.
Вы помните, что this — это указатель. Значение указателя — это адрес. Чтобы получить значение указателя, его следует разыменовывать. Разыменование указателя выглядит как:
*ptr
Указатель this разыменовывается точно так же.
*this
Помещая эти две строки в начале и в конце тела операции присваивания, мы уменьшаем вероятность возникновения утечек памяти из-за этой операции. Если вы запомнили приведенный здесь синтаксис копирования и присваивания и, определяя новый класс, сразу определили и их тоже, то это уже полдела.
Примеры, приведенные в этом и предыдущих разделах, показывают общность синтаксиса копирования и присваивания. В табл. 17.1 приведена дополнительная информация, касающаяся копирования и присваивания. Используйте эту таблицу при проработке вариантов проекта.
Функция |
Наследование |
Виртуальность |
Возвращаемое значение |
Член класса |
Создается по умолчанию |
Копирование |
Нет |
Нет |
Нет |
Да |
Да |
Присваивание |
Нет |
Да |
Есть |
Да |
Да |
Зачем C++ требует определения этих функций-членов?
Язык C++ не слишком сильно ограничивает свободу программистов в методах разработки программного обеспечения. В частности, он не навязывает вам способы копирования и присваивания. Количество и разнообразие ситуаций, в которых происходит копирование объектов, удивительно велико. Для очень простых объектов, состоящих из одного-двух элементов, затраты на копирование незначительны, но для более сложных, таких как графический интерфейс пользователя или комплексные типы данных, оперирующие с динамической памятью, издержки на копирование существенно возрастают.