Программирование >>  Инициализация объектов класса, структура 

1 ... 127 128 129 [ 130 ] 131 132 133 ... 395


string *pstr type = new string( Brontosaurus ); if ( pstr type->empty() )

строкой м1 бы поступили таким образом:

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

auto ptr< string > pstr auto( new string( Brontosaurus ) ); if ( pstr type->empty() )

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

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

Создатели шаблона класса 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, стоящий справа от оператора присваивания, передает право

pstr auto( new string( Brontosaurus ) ); Предположим, что мы хотим выполнить какую-то операцию со строками. С обычной



auto ptr< int > p1( new int( 1024 ) );

Аналогично ведет себя и операция присваивания. Пусть у нас есть два объекта auto ptr:

auto ptr< int > p2( new int( 2048 ) );

Мы можем скопировать один объекта auto ptr в другой с помощью этой операции:

p1 = p2;

Перед присваиванием объект, на который ссылался p1, удаляется.

После присваивания p1 владеет объектом типа int со значением 2048. p2 больше не может использоваться как ссылка на этот объект.

Третья форма определения объекта auto ptr создает его, но не инициализирует

пока не сс1лается ни на какой объект

значением указателя на область памяти из хипа. Например:

auto ptr< int > p auto int;

Поскольку p auto int не инициализирован адресом какого-либо объекта, значение хранящегося внутри него указателя равно 0. Разыменование таких указателей приводит к

ошибка: разыменование нулевого указателя if ( *p auto int != 1024 )

непредсказуемому поведению программы:

*p auto int = 1024;

int *pi = 0; Обычный указатель можно проверить на равенство 0:

if ( pi ! = 0 )

А как проверить, адресует auto ptr какой-либо объект или нет? Операция get() возвращает внутренний указатель, использующийся в объекте auto ptr. Значит, мы

проверяем, указывает p auto int на объект if ( p auto int.get() != 0 && *p auto int != 1024 )

должны применить следующую проверку:

владения и ответственность auto ptr, стоящему слева. В нашем примере ответственность за уничтожение строки несет pstr auto2, а не pstr auto. pstr auto больше не может употребляться для ссылки на эту строку.



else

хорошо, присвоим ему значение

auto ptr? Это делается с помощью операции reset() . Например:

p auto int.reset( new int( 1024 ) ); Объекту auto ptr нельзя присвоить адрес объекта, созданного с помощью оператора

void example() {

инициазируется нулем по умолчанию

auto ptr< int > pi;

не поддерживается pi = new int( 5 ) ;

new:

В этом случае надо использовать функцию reset() , которой можно передать указатель или 0, если мы хотим обнулить объект auto ptr. Если auto ptr указывает на объект и является его владельцем, то этот объект уничтожается перед присваиванием нового

auto ptr< string >

pstr auto( new string( Brontosaurus ) );

Brontosaurus уничтожается перед присваиванием

значения внутреннему указателю auto ptr. Например:

pstr auto.reset( new string( Long-neck ) ); В последнем случае лучше, используя операцию assign() , присвоить новое значение

более эффективн способ присвоить новое значение используем операцию assign() существующей строке, чем уничтожать одну строку и создавать другую:

pstr auto->assign( Long-neck );

Одна из трудностей программирования состоит в том, что получить правильный результат не всегда достаточно. Иногда наклад1ваются и временные ограничения. Такая мелочь, как удаление и создание заново строкового объекта, вместо использования функции assign() при определенных обстоятельствах может вызвать значительное замедление работы. Подобные детали не должны вас беспокоить при проектировании, но при доводке программы на них следует обращать внимание.

*p auto int = 1024;

Если auto ptr ни на что не указывает, то как заставить его адресовать что-либо? Другими словами, как мы можем присвоить значение внутреннему указателю объекта



1 ... 127 128 129 [ 130 ] 131 132 133 ... 395

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