Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

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

Предкомпилированные заголовки | Понятие пространства имен | Стандартные конструкторы | Порядок конструирования и разрушения объектов | Множественное наследование | Проблема повторяющихся базовых классов | Замена множественного наследования наследованием от интерфейсов в других языках объектно-ориентированного программирования | Понятие константного метода | Проблемы, порождаемые наличием константных методов | Рекомендации по работе со ссылками |


Читайте также:
  1. Античное понятие о мелосе.
  2. Базовая структура унифицированного указателя ресурса
  3. Безубыточность: понятие, порядок определения, факторы изменения.
  4. Брак и семья. Семья и ее функции, понятие об ответственности родителей.
  5. В христианском учении понятие «счастье» делится на мирское и духовное
  6. В. Понятие типа кадра
  7. В.1. Понятие производственной мощности предприятия

 

Класс 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[].


Дата добавления: 2015-11-16; просмотров: 66 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Типичные ошибки при работе со ссылками| Перегрузка операторов преобразования типа

mybiblioteka.su - 2015-2024 год. (0.007 сек.)