See also ebooksgratis.com: no banners, no cookies, totally FREE.

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
Privacy Policy Cookie Policy Terms and Conditions
Умный указатель — Википедия

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

Материал из Википедии — свободной энциклопедии

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

Содержание

[править] Владеющие указатели

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

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

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

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

[править] Указатели с подсчётом ссылок

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

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

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

[править] Реализации

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

Объект обязан хранить внутри себя неотрицательное целое, которое означает число внешних указателей, ссылающихся на этот объект.

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

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

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

[править] Проблема циклических ссылок

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

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

[править] Примеры реализаций

На других языках


aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -