Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конструкторы и деструкторы.doc
Скачиваний:
24
Добавлен:
18.04.2015
Размер:
184.83 Кб
Скачать

Конструктор копирования

Назначение:

  1. создать объект полностью совпадающий с уже созданным;

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

  1. функция передает в некоторую переменную объект класса, фактически этот объект сначала создается в функции как локальная переменная, и лишь затем копируется в переменную, стоящую в левой части выражения.

Операции копирования объектов выполняет конструктор копирования.

В большинстве случаев компилятор предоставляет нам конструктор копирования по умолчанию, обеспечивая правильное копирование.

Копирование по умолчанию:

class T {

int x, y ;

public:

T ( int tx , int ty ) { x = tx ; y = ty ; }

Int GetX ( ) { return X; }

int GetY ( ) { return y; }

friend T sum ( T, T);

};

void Print ( T obj )

{ cout<<’\n’<<”x=”<<obj.GetX( ) <<” y=”<<obj.GetY( ); }

T sum ( T obj1 , T obj2 )

{ obj1. x + =obj2. x ;

obj1. y + =obj2. y ;

return obj1 ; }

#include <iostream.h>

void main () {

T e1 ( 1, 10); //создали объект, вызвав конструктор с параметрами

Print ( e1 ); // первое копирование

T e2 = e1; // второе копирование

Print ( e2 ); // третье копирование

T e3 = sum ( e1, e2 ) ; // четвертые копирования

Print (e3); // пятое копирование

}

// выведется:

// x= 1 y = 10

x= 1 y = 10

x= 2 y = 20

Определение конструктора копирования

Конструктор копирования должен иметь для данного класса такой вид:

1. T ( T obj ) { x = obj.x ; y = obj. y } // не верно!

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

Рекурсию можно избежать, если не копировать объект в конструктор, а использовать передачу параметра по ссылке:

2. T ( T & obj ) { x = obj.x ; y = obj. y }

И последнее – необходимо ввести запрет на модификацию копируемого параметра для этого используется ключевое слово const:

3. T ( const T & obj ) { x = obj.x ; y = obj. y }

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

Рассмотрим, как происходит копирование.

Как удостоверится, что

- при копировании объекта,

- при передачи объекта в функцию,

-при возвращении функцией объекта в некоторую

переменную (также объект)

вызывается конструктор копированияпо умолчанию, иликонструктор копирования явно определенный в классе?

Для того, чтобы зафиксировать факт вызова конструктора копирования, мы правильное копирование (в программе написанной выше, конструктор варианта 3 вызывается по умолчанию) заменим на копирование с приращением:

class T {

int x, y ;

public:

T ( int tx , int ty ) { x = tx ; y = ty ; }

T (const T & obj) { x = obj.x+1 ; y = obj. y +1 }