Класс auto_ptr. Передача прав владения в auto_ptr

   
На этом шаге мы рассмотрим особенности работы с указателями и конструкторами типа auto_ptr.

   
Тип auto_ptr поддерживает семантику строгой принадлежности. Иначе говоря, поскольку тип auto_ptr
удаляет объект, на который он ссылается, этот объект не может "принадлежать" другим объектам. Два и более
экземпляра auto_ptr не должны одновременно быть владельцами одного объекта. К сожалению, в программе
такая ситуация не исключена (например, если два экземпляра auto_ptr инициализируются одним и тем же
объектом). Программист обязан позаботиться о том, чтобы этого не случилось.

   
Возникает вопрос: как работают копирующий конструктор и оператор присваивания типа auto_ptr? В обычном
варианте эти операции копируют данные из одного объекта auto_ptr в другой, но в нашем случае это создает
ситуацию, при которой один объект принадлежит сразу двум экземплярам auto_ptr. Проблема решается просто,
но у этого решения есть одно важное следствие: копирующий конструктор и оператор присваивания передают
"право владения" тем объектом, на который ссылается auto_ptr.

   
Рассмотрим следующий пример использования копирующего конструктора:

// Инициализация auto_ptr новым объектом 
std::auto_ptr<ClassA> ptr1(new ClassA);
// Копирование auto_ptr
// - право владения объектом передается от ptr1 к ptr2
std::auto_ptr<ClassA> ptr2(ptr1);

   
После выполнения первой команды объект, созданный оператором new, принадлежит ptr1. Вторая
команда передает npaво владения от ptr1 к ptr2. Следовательно, после выполнения второй команды
объект, созданный оператором new, принадлежит ptr2, a ptr1 перестает быть владельцем этого объекта.
Объект, созданный конструкцией new ClassA, удаляется только один раз - при уничтожении ptr2.

   
Оператор присваивания поступает аналогичным образом:

// Инициализация auto_ptr новым обьектом
std::auto_ptr<ClassA> ptr1(new ClassA);
std::auto_ptr<ClassA> ptr2;      // Создание другого экземпляра auto_ptr
ptr2 = ptr1; // Присваивание auto_ptr
// - принадлежность объекта передается от ptr1 к ptr2

   
Обратите внимание: смена владельца не является простым копированием. Во всех случаях передачи права владения
предыдущий владелец (ptr1 в нашем примере) перестает им быть. В результате после передачи права владения
предыдущий владелец содержит null-указатель. Подобное поведение серьезно противоречит общим принципам
инициализации и присваивания в языках программирования. Копирующий конструктор модифицирует объект,
используемый для инициализации нового объекта, а оператор присваивания модифицирует правую часть операции
присваивания. Программист должен сам следить за тем, чтобы программа не пыталась разыменовать экземпляр
auto_ptr, переставший владеть объектом и содержащий null-указатель.

   
Новое значение, присваиваемое auto_ptr, также должно относиться к типу auto_ptr. Присваивание
обычных указателей не допускается:

std::auto_ptr<ClassA> ptr; // Создание auto_ptr
ptr = new ClassA; // ОШИБКА
ptr = std::auto_ptr<ClassA>(new ClassA);    // ОК. Удаление старого объекта
                                            // и получение нового.

   
На следующем шаге мы рассмотрим источник и приемник auto_ptr.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий