|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Понятие автоматического указателя (auto_ptr)
Класс 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[]. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.004 сек.) |