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

Копирование также может быть реализовано компилятором. Компилятор Borland C++ при необходимости может производить оптимизацию кода, в процессе которой возможно создание временных объектов.

Разница между копированием и присваиванием

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

Ниже мы рассмотрим все варианты вызова на примере объектов у и z произвольного класса х. Для начала возьмем следующую форму вызова:

Х y(z);

•*

Это прямой вызов конструктора копий класса х. Объект у — вызывающий, а объект z выступает в роли аргумента. Поскольку синтаксис конструктора копий выглядит как

X::X( const X& rhs) ;

то в нашем случае указатель this в конструкторе копий ссылается на у, а псевдоним rhs является адресом z. В данном примере создается новый объект у, так что совершенно несомненно вызывается конструктор копий.

В следующем примере также происходит вызов конструктора копий, но уже не столь очевидный:

Х у = z;

Присутствие в этой строке знака равенства заставляет предположить, что здесь происходит присваивание. Однако помимо этого налицо факт создания нового объекта класса х. Если бы в этом операторе использовалась операция присваивания, то в развернутом виде он выглядел бы так:

у.operator = (z); // Что недопустимо

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

В последнем примере и у, и z уже существуют и объекту у с помощью операции присваивания присваивается значение объекта z:

Х у, z;

у = z; // вызов операции присваивания