Конструктор копирования должен иметь для данного класса такой вид:
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 }
int GetX () { return x; }
int GetY () { return y; }
friend T sum (T, T);
};