АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Понятие автоматического указателя (auto_ptr)

Читайте также:
  1. I. Договоры товарищества. Понятие, типы и виды
  2. I. ЛИЗИНГОВЫЙ КРЕДИТ: ПОНЯТИЕ, ИСТОРИЯ РАЗВИТИЯ, ОСОБЕННОСТИ, КЛАССИФИКАЦИЯ
  3. I. Общее понятие о вещных правах на чужую вещь
  4. I. Общее понятие о залоговом праве
  5. I. Общее понятие о лице в праве
  6. I. Общее понятие о юридическом лице и виды юридического лица
  7. I. Общее понятие об опеке
  8. I. Понятие и анализ оборотного капитала
  9. I. Понятие о договоре
  10. I. Понятие о завещании и его составление (форма)
  11. I. Понятие о семейном праве
  12. I. Понятие об обязательстве как обязательственном отношении

 

Класс auto_ptr – это шаблонный класс для контроля над распределением динамической памяти.

 

void remodel (string & str)

{

string * ps = new string(str);

str = ps;

return;

}

 

При каждом вызове функции происходит выделение памяти в куче, однако память не освобождается. Это приводит к утечкам памяти. Решение проблемы очевидно – не забыть освободить память:

 

delete ps;

 

перед оператором return. Однако, решение, которое содержит фразу "не забыть", не является идеальным. Иногда разработчик не желает помнить об этом. Или разработчик помнит, но случайно удалил или закомментировал строку. И даже в том случае, когда это решение используется, могут возникать проблемы.

 

void remodel(string & str)

{

string * ps = new string (str);

if (weird_thing())

throw exception();

str = *ps;

delete ps;

return;

}

 

При возникновении исключительной ситуации операция delete вообще не будет достигнута, и снова появится утечка памяти.

 

Такие ошибки исправимы, но желательно иметь лучшее решение. Программа должна выполнять некоторые дополнительные действия после удаления указателя. В базовых типах подобной функциональности нет. Для классов такая возможность предоставлена через деструкторы. Если бы ps был объектом, то деструктор бы освобождал память, на которую указывал объект, при удалении объекта. Это и есть основная идея использования auto_ptr.

 

Шаблон аutо_рtr определяет объект, которому присваивается адрес области памяти, полученный вызовом операции new. Когда объект auto_ptr удаляется, его деструктор использует delete для освобождения памяти. Таким образом, присвоив адрес, возвращаемый операцией new, объекту auto_ptr, не нужно беспокоиться о последующем высвобождении памяти. Это будет сделано автоматически, при удалении объекта.

 

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

 

template <class Х>

class auto_ptr

{

public:

explicit auto_ptr (X* р =0) throw(); // конструктор не должен генерировать исключения

...

};

Auto_ptr<double> pd(new double);

Auto_ptr<string> ps(new string);

 

Допустимо только явное преобразование их простого указателя в интеллектуальный.

Недопустимо:

String helloStr(“Hello”);

auto_ptr<string> pHello(&helloStr);

 

В С++11 шаблон auto_ptr объявлен устаревшим, в качестве альтернативы предлагаются shared_ptr и unique_ptr.

 

Auto_ptr:

auto_ptr<string> p1(new string(“OOP”));

auto_ptr<string> p2;

p2=p1

cout << p1 // p1 утрачивает право владения указателем и перестает ссылаться на строку. Может привести к Segmentation fault (core dump).

Shared_ptr:

 

shared_ptr<string> p1(new string(“OOP”));

shared_ptr<string> p2;

p2=p1

cout << p1 //операция завершится успешно, т.к. p1и p2 указывают на один и тот же объект. Используется стратегия подсчета ссылок. При p1=p2 значение счетчика ссылок увеличилось на 1. В конце программы сначала вызовется деструктур p2, который уменьшит количество ссылок на 1. delete выполнится, когда счетчик ссылок станет 0.

Unique_ptr:

unique_ptr<string> p1(new string(“OOP”));

unique_ptr<string> p2;

p2=p1 // будет сгенерирована ошибка во время компиляции

 

Но если программа пытается присвоить один объект unique_ptr другому, компилятор не препятствует этому, если исходный объект является временным значением, и запрещает это, если исходный объет существует некоторое время.

 

Auto_ptr и shared _ ptr не могут использоваться с массивами (память, выделенная как new[]). Unique_ptr может использоваться как с объектами, память для которых выделена операцией n ew, так и с объектами, память для которых выделена операцией new[].


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.007 сек.)