printКлассы

printКонструктор копий

Определение: Конструктор копий – это конструктор, у которого один аргумент – ссылка на константный объект определяемого класса.

Синтаксис: имя класса(const имя класса&);

Задача: Создание точной копии объекта, переданного в качестве аргумента.

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

Замечания:
  • Если конструктор копий не определяется программистом, компилятор создает его сам. В этом автоматически созданном конструкторе вызываются конструкторы копий для всех базовых классов и полей.
  • В большинстве случаев нет необходимости определять конструктор копий самостоятельно.
  • Но если класс содержит указатели на динамически выделяемую память, то при создании копии произойдёт дублирование идентичности этих значений. В результате изменение одного объекта приведёт к изменению другого объекта. Поэтому в случае использования указателей необходимо определять конструктор копий самостоятельно.
  • Если создание копий не требуется, нужно написать =delete после заголовка.
  • Если создание копий разрешено только в методах класса и подходит определение, создаваемое компилятором, то нужно поместить заголовок в закрытый раздел и написать =default после заголовка.

Примеры:
class Stack {
  int size,t;
  int *s;
public:
  Stack(const Stack &); // конструктор копий
  ...
};
Stack::Stack(const Stack &a):
  size(a.size),t(a.t),s(new int[size])
{
  for(int i=0; i<=t; ++i)
    s[i]=a.s[i];
}
Stack reverse(Stack x) // параметр x функции reverse передается по значению
{ Stack z(100);
  while(!x.isEmpty())
  { z.push(x.top());
    x.pop();
  }
  return z; // при возврате сначала вызывается конструктор копий, 
            // чтобы создать копию z, а затем деструктор для z
}
int main()
{
  Stack a(100);
  ...
  Stack b(a); // b - это копия a
  ...
  a=reverse(b); // перед вызовом reverse будет вызван конструктор копий создания копии b
            // также компилятор выделит память для возращаемого значения
            // для инициализации этой памяти при завершении reverse будет
            // вызван конструктор копий
}
loading