Программирование >>  Операторы преобразования типа 

1 ... 12 13 14 [ 15 ] 16 17 18 ... 239


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

Неправильное использование класса auto ptr

Тип auto ptr создавался для вполне определенных целей, а именно для предотвращения утечки ресурсов при обработке исключений. К сожалению, в прошлом принципы работы auto ptr изменялись, а стандартная библиотека не содержит других умных указателей, поэтому программисты часто неправильно используют auto ptr. Ниже приведены рекомендации, которые помогут предотвратить ошибки с применением auto ptr.

О Указатели auto ptr не могут совместно владеть объектами. Экземпляр auto ptr }te должен ссылаться на объект, принадлежащий другому экземпляру auto j3tr (или другому объекту). В противном случае, если объект будет удален первым указателем, второй указатель начнет ссылаться на уничтоженный объект и любые попытки чтения или записи приведут к катастрофе.

О Тип auto ptr 7te поддерживает массивы. Запрещено использовать тип auto ptr для ссылок на массивы. Дело в том, что объект auto ptr для принадлежащего ему объекта вызывает оператор delete, а не delete[]. В стандартной библиотеке С++ не существует а11алогнчного класса, поддерживающего семантику auto ptr для массивов. Вместо этого в библиотеку включены контейнерные классы для работы с наборами данных (см. главу 5).

О Тип auto ptr не является - универсально умным указателем. Тип aiJto ptr не предназначен для других проблем, при решении которых применяются умные указатели. В частности, auto ptr не подходит для подсчета ссылок (указатели с подсчетом ссылок гарантируют, что объект будет уничтожен только после удаления последнего из нескольких умных указателей, ссылающихся на объект).

О Тип auto ptr не отвечает требованиям к элементам контейнеров. Тип auto ptr не удовлетворяет одному из основных требований к элементам стандартных контейнеров, а именно: после копирования или присваивания auto ptr источник и приемник не эквивалентны. Присваивание или копирование объекта auto ptr приводит к модификации экземпляра-источника, потому что операция фактически передает значение, вместо того чтобы его копировать. Следовательно, объекты auto ptr не могут использоваться в качестве элементов стандартных контейнеров. К счастью, архитектура языка и библиотеки предотвращает эту ошибку при компиляции в среде, соответствующей стандарту.

К сожалению, неправильное применение auto ptr в отдельных случаях работает, из-за этого неконстантные объекты auto ptr потенциально так же опасны, как обычные указатели. Возможно, вам повезет, и неправильное использование



auto ptr не приведет к сбою, но на самом деле это скорее невезение, чем везение, - вы даже не узнаете о том, что допустили ошибку.

Реализация умных указателей для подсчета ссылок рассматривается на с. 144 и 226. Такие указатели удобны при совместном использовании элементов в разных контейнерах.

Примеры использования класса auto.ptr

Первый пример демонстрирует передачу права владения при работе с auto ptr,

util/autoptrl.cpp Iinclude <1o5treani> Iinclude <шетогу> using namespace std;

/* Определение оператора вывода для auto ptr * - вывод значения объекта или NULL */

template <class Т>

ostreamS operator (ostreamS strm, const auto ptr<T>& p) {

Указывает ли p на объект? if (p.getO - NULL) {

strm NULL ; НЕТ: вывести строку NULL

else (

strm *p; ДА: вывести объект

return strm;

int mainO {

auto ptr<int> pCnew int(42)); auto ptr<int> q;

cout after initialization: endl: cout p; p endl; cout q: q endl:

q = p:

cout after assigning auto pointers: endl;

cout p: p endl:

cout q: q endl;

*q += 13; Модификация обьекта. принадлежащего q

p = q;

cout after change and reassignment: endl:



cout р: р endl: cout q: q endl;

Результат работы программы выглядит так:

after initialization: р: 42 q: NULL

after assigning auto pointers: p: NULL q: 42

after change and reassignment; p: 55 q: NULL

Обратите внимание: второй параметр функции оператора вывода объявлен как константная ссылка, поэтому aiJto ptr используется без передачи права владения.

Как упоминалось на с. 56, экземпляры auto ptr не могут инициализироваться с присваиванием, а также им не могут присваиваться обычные указатели:

std::autoj)tr<1nt> p(new lntC42)): OK

std::auto ptr<1nt> p = new intC42); ОШИБКА

p = std::auto ptr<int>(new int(42)); OK p = new int(42); ОШИБКА

Дело в том, что конструктор, используемый для создания auto ptr на базе обычного указателя, объявлен с ключевым словом explicit (см. с. 34).

Следующий пример демонстрирует поведение константных объектов auto ptr:

util/autoptr2.cpp #include <iostreani> Iinclude <meniory> using namespace std:

/* Определение оператора вывода для auto ptr * - вывод значения объекта или NULL */

template <class Т>

ostream& operator (05tream& strm. const auto ptr<T>& p)

Указывает ли p на объект? if (p.getO == NULL) {

strm NULL : НЕТ: вывести строку NULL

else {

strm *p; ДА: вывести объект



1 ... 12 13 14 [ 15 ] 16 17 18 ... 239

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика