С++ для начинающих

         

Шаблон auto_ptr * - часть 2


Предположим, что мы хотим выполнить какую-то операцию со строками. С обычной строкой мы бы поступили таким образом:

string *pstr_type = new string( "Brontosaurus" );

if ( pstr_type->empty() )

    // ошибка, что-то не так

А как обратиться к операции empty(), используя объект auto_ptr? Точно так же:

auto_ptr< string > pstr_auto( new     string( "Brontosaurus" ) );

if ( pstr_type->empty() )

    // ошибка, что-то не так

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

Что произойдет, если мы проинициализируем pstr_auto2 значением pstr_auto, который является объектом auto_ptr, указывающим на строку?

// кто несет ответственность за уничтожение строки?

auto_ptr< string > pstr_auto2( pstr_auto );

Представим, что мы непосредственно инициализировали один указатель на строку другим:

string *pstr_type2( pstr_type );

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

В противоположность этому шаблон класса auto_ptr поддерживает понятие владения. Когда мы определили pstr_auto, он стал владельцем строки, адресом которой был инициализирован, и принял на себя ответственность за ее уничтожение.

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

Когда один объект auto_ptr инициализируется другим или получает его значение в результате присваивания, одновременно он получает и право владения адресуемым объектом. Объект auto_ptr, стоящий справа от оператора присваивания, передает право владения и ответственность auto_ptr, стоящему слева. В нашем примере ответственность за уничтожение строки несет pstr_auto2, а не pstr_auto. pstr_auto больше не может употребляться для ссылки на эту строку.




Содержание  Назад  Вперед