C++.Бархатный путь


Конструктор копирования - часть 2


И всё же выполнение этой тривиальной программы приводит к неожиданному результату: создавая два объекта, мы наблюдаем всего одно сообщение о работе конструктора.

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

Так и есть! Такой конструктор существует и называется конструктором копирования. Вместе с конструктором умолчания, конструктор копирования входит в обязательный набор конструкторов для любого класса. Реализация механизма копирования значений для транслятора не является неразрешимой задачей. Конструктор копирования всего лишь создаёт копии объектов. Этот процесс реализуется при помощи стандартного программного кода. И построить такой код транслятор способен самостоятельно.

Здесь и далее, в примерах нами будет применяться операция присвоения = . В определённом смысле эта операция подобна конструктору. Реализующий эту операцию код автоматически создаётся на этапе трансляции для любого класса. Как и генерация кода стандартных конструкторов, это не самая сложная задача.

Подобно конструктору умолчания, конструктор копирования наряду с уже известной нам формой вызова ComplexType CDw2 = CDw1;

имеет несколько альтернативных, приводящих к аналогичному конечному результату вызовов:

ComplexType CDw2(CDw1); ComplexType CDw3 = ComplexType(CDw1);

Обе альтернативные формы вызова напоминают нам уже известные формы вызова конструкторов с параметрами. Чтобы восстановить структуру заголовка конструктора копирования, мы должны лишь определить тип его параметра.

На первый взгляд, здесь всё просто. В качестве значения параметра конструктору передаётся имя объекта, значит можно предположить, что тип параметра конструктора копирования соответствует данному классу. Так, в нашем случае, конструктор копирования класса ComplexType должен был бы иметь параметр типа ComplexType. Однако это не так. И вот почему.

В C++ конструктор копирования является единственным средством создания копий объекта.

С другой стороны, конструктор копирования - это конструктор, который поддерживает стандартный интерфейс вызова функций. Это означает, что параметры при обращении к конструктору, подобно параметрам функции передаются по значению. Если выражение вызова содержит значения параметров, то в ходе его реализации в области активации функции создаётся копия этих значений.

В таком случае, вызов конструктора копирования сопровождался бы построением в области активации конструктора копии объекта. Для этого пришлось бы использовать конструктор копирования как единственное средство построения копии объекта. Таким образом, вызов подобного конструктора копирования сопровождался бы бесконечной рекурсией.

Итак, КОНСТРУКТОР КОПИРОВАНИЯ КЛАССА X НЕ МОЖЕТ ИМЕТЬ ПАРАМЕТР ТИПА X. Это аксиома.

На самом деле, в конструкторе копирования класса X в качестве параметра используется ссылка на объект этого класса. Причём эта ссылка объявляется со спецификатором const. И в этом нет ничего странного. Как известно, выражение вызова функции с параметром типа X ничем не отличается от выражения вызова функции, у которой параметром является ссылка на объект типа X. При вызове такой функции не приходится копировать объекты как параметры. Передача адреса не требует копирования объекта, а значит, при этом не будет и рекурсии.

Конструктор копирования - обязательный элемент любого класса. Он также может быть переопределён подобно конструктору умолчания. При этом работа со ссылками в конструкторе копирования не требует явного использования операции разыменования. А спецификатор const (конструктор копирования работает с адресом объекта) предохраняет объект-параметр от случайной модификации в теле конструктора.

| |

 




- Начало -  - Назад -  - Вперед -