Умный указатель

Умный указатель

Умный указатель (англ. smart pointer) — класс (обычно шаблонный), имитирующий интерфейс обычного указателя и добавляющий некую новую функциональность, например проверку границ при доступе или очистку памяти.

Содержание

Владеющие указатели

Чаще всего умный указатель инкапсулирует семантику владения ресурсом. В таком случае он называется владеющим указателем.

Владеющие указатели применяются для борьбы с утечками памяти и висячими ссылками. Утечкой памяти называется ситуация, когда в программе нет ни одного указателя, хранящего адрес объекта, созданного в динамической памяти. Висячей ссылкой (англ. Dangling pointer) называется указатель, ссылающийся на уже удалённый объект. Семантика владения для динамически созданных объектов означает, что удаление или присвоение нового значения указателю будет согласовано с временем жизни объекта.

Простые владеющие указатели

Такие указатели при присвоении нового значения или удалении сами удаляют объект. Их недостатком являются трудности с передачей объекта за пределы области видимости указателя.

Указатели с подсчётом ссылок

Такие обычно используются с объектами, имеющими специальные операции «увеличить число ссылок» (AddRef() в COM) и «уменьшить число ссылок» (Release() в COM). Чаще всего такие объекты унаследованы от специального класса или интерфейса (например, IUnknown в COM).

При появлении новой ссылки на объект вызывается операция «увеличить число ссылок», а при уничтожении — «уменьшить число ссылок». Если в результате операции «уменьшить число ссылок» число ссылок на объект становится равным нулю, то объект удаляется.

Такая методика называется автоматическим подсчётом ссылок. Она согласует число указателей, хранящих адрес объекта, с числом ссылок, хранящимся в объекте, а при достижении этим числом нулевого значения приводит к удалению объекта. Её преимуществами являются относительно высокие надёжность, быстродействие и простота реализации в C++. Недостатком является усложнение использования в случае возникновения циклических ссылок (необходимость пользоваться "слабыми ссылками").

Реализации

В COM объекты с подсчётом ссылок реализуются следующим образом:

  • Объект обязан хранить внутри себя неотрицательное целое, которое означает число внешних указателей, ссылающихся на этот объект.
  • При присваивании указателю адреса нового объекта указатель вызывает у объекта метод AddRef(). Если перед этим указатель ссылался на другой объект, то сначала вызывается метод Release() прежнего объекта. При удалении указателя (выходе его из области видимости или разрушении объекта, полем которого он являлся), если этот указатель ссылается на существующий объект, указатель вызывает метод Release() объекта.
  • Реализация метода Release() каждый раз уменьшает число ссылок на единицу и сразу проверяет новое значение. Если число ссылок стало равно нулю, метод Release() вызывает удаление объекта.

Другой вариант реализации используется в boost::shared_ptr. В этом случае, счетчики ссылок хранятся в специальной структуре данных вне объекта.

Проблема циклических ссылок

Предположим, есть два объекта и в каждом из них по владеющему указателю. Указателю в первом объекте присвоим адрес второго объекта, а указателю во втором — адрес первого объекта. Если теперь всем внешним (то есть не хранящимся внутри этих объектов) указателям на два данных объекта присвоить новые значения, то указатели внутри объектов по-прежнему будут владеть друг другом и будут оставаться в памяти. В результате возникнет ситуация, когда к объектам невозможно получить доступ, то есть утечка памяти.

Проблема циклических ссылок решается либо путем соответствующего проектирования структур данных, либо использованием сборки мусора, либо использованием двух видов ссылок: сильные (владеющие) и слабые (невладеющие, напр. boost::weak_ptr).

Примеры реализаций

Cсылки


Wikimedia Foundation. 2010.

Игры ⚽ Поможем написать реферат

Полезное


Смотреть что такое "Умный указатель" в других словарях:

  • Указатель (тип данных) — У этого термина существуют и другие значения, см. Указатель. Диаграмма указателей Указатель (пойнтер, англ. pointer)  переменная, диапазон значений которой состоит из адресов ячеек памяти и специального значения  нулевого адреса.… …   Википедия

  • Smart pointer — Умный указатель (англ. smart pointer) класс (обычно шаблонный), имитирующий интерфейс обычного указателя и добавляющий некую новую функциональность, например проверку границ при доступе или очистку памяти. Содержание 1 Владеющие указатели 1.1… …   Википедия

  • New (C++) — В языке программирования C++, new оператор, обеспечивающий выделение динамической памяти в куче. За исключением формы, называемой «размещающей формой new», new пытается выделить достаточно памяти в куче для размещения новых данных и, в случае… …   Википедия

  • new (C++) — В языке программирования C++, new оператор, обеспечивающий выделение динамической памяти в куче. За исключением формы, называемой «размещающей формой new», new пытается выделить достаточно памяти в куче для размещения новых данных и, в случае… …   Википедия

  • Утечка памяти — (англ. memory leak) процесс неконтролируемого уменьшения объёма свободной оперативной памяти (RAM) компьютера, связанный с ошибками в работающих программах, вовремя не освобождающих ненужные уже участки памяти, или с ошибками системных служб …   Википедия

  • Утечки памяти — Утечка памяти (англ. memory leak) процесс неконтролируемого уменьшения объёма свободной оперативной памяти (RAM) компьютера, связанный с ошибками в работающих программах, вовремя не освобождающих ненужные уже участки памяти, или с ошибками… …   Википедия

  • Россия. Русский язык и Русская литература: История русской литературы — История русской литературы для удобства обозрения основных явлений ее развития может быть разделена на три периода: I от первых памятников до татарского ига; II до конца XVII века; III до нашего времени. В действительности эти периоды резко не… …   Энциклопедический словарь Ф.А. Брокгауза и И.А. Ефрона

  • Пушкин, Александр Сергеевич — — родился 26 мая 1799 г. в Москве, на Немецкой улице в доме Скворцова; умер 29 января 1837 г. в Петербурге. Со стороны отца Пушкин принадлежал к старинному дворянскому роду, происходившему, по сказанию родословных, от выходца "из… …   Большая биографическая энциклопедия

  • Русский язык — I.Восточно славянские языки в дофеодальную эпоху. Место русского языка в ряду других языков. II.Консолидация восточно славянских говоров, Образование отдельных восточно славянских языков. III.Возникновение письменного (литературного) языка у… …   Литературная энциклопедия

  • Библиотека для чтения — Журнал словесности, наук, художеств, критики, новостей и мод. Это первый русский толстый журнал того типа, к которому привыкли в настоящее время. Он был задуман О. И. Сенковским вместе с известным книгопродавцем А. Ф. Смирдиным. Предпринимая… …   Энциклопедический словарь Ф.А. Брокгауза и И.А. Ефрона


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»