Шаг 60.
Библиотека STL.
Вспомогательные средства. Класс 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.




Предыдущий шаг Содержание Следующий шаг