7.1.5. Копирование, присвоение и удаление

Кроме определения способа инициализации своих объектов, классы контролируют также то, что происходит при копировании, присвоении и удалении объектов класса. Объекты копируются во многих случаях: при инициализации переменной, при передаче или возвращении объекта по значению (см. раздел 6.2.1 и раздел 6.3.2). Объекты присваиваются при использовании оператора присвоения (см. раздел 4.4). Объекты удаляются, когда они прекращают существование, например, при выходе локального объекта из блока, в котором он был создан (см. раздел 6.1.1). Объекты, хранимые в векторе (или массиве), удаляются при удалении вектора (или массива).

Если мы не определим эти операции, компилятор создаст их сам. Обычно создаваемые компилятором версии выполняются, копируя, присваивая или удаляя каждую переменную-член объекта. Например, когда в приложении книжного магазина (см. раздел 7.1.1) компилятор выполняет следующее присвоение:

total = trans; // обработать следующую книгу

оно выполняется, как будто было написано так:

// присвоение по умолчанию для Sales_data эквивалентно следующему:

total.bookNo = trans.bookNo;

total.units_sold = trans.units_sold;

total.revenue = trans.revenue;

Более подробная информация об определении собственных версий этих операторов приведена в главе 13.

Некоторые классы не могут полагаться на синтезируемые версии

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

Однако следует заметить, что большинство классов, нуждающихся в динамической памяти, способны (и должны) использовать классы vector или string, если им нужно управляемое хранение. Классы, использующие векторы и строки, избегают сложностей, связанных с резервированием и освобождением памяти.

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

Пока вы еще не знаете, как определить операторы, описанные в главе 13, ресурсы, резервируемые вашими классами, должны храниться непосредственно как переменные-члены класса.

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК