A shared_ptr<T>
обычно реализуется в виде двух указателей.Один для данных объекта, а другой для структуры, которая выглядит следующим образом:
[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[type-erased destroyer data]
, где [object ptr]
указывает на фактический объект.
Когда вы копируете shared_ptr
,он создает еще один указатель на вышеуказанные данные (и на реальный объект) и увеличивает его часть [strong reference count]
.Слабые указатели ведут себя аналогично, но вместо этого увеличивают [weak reference count]
(когда сильное равно 0, а слабое ненулевое - вызывается уничтоженный по типу разрушитель, но блок управления остается).
В качестве отступления, когда выВызовите make_shared
:
[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[object data]
, где указатель на объект теперь указывает на [object data]
в конце блока управления.Это уменьшает количество выделений до одного.
Необходим отдельный указатель блока данных и управления из-за особенностей, таких как тот факт, что shared_ptr для производного может быть изменен на shared_ptr на базовый;это требует корректировки значения указателя во многих случаях.Точно так же конструктор псевдонимов общего ptr позволяет блоку управления и указанному объекту быть полностью не связанными.
Взято из ответа @ Estinox «что не является ответом», здесь это Channel9 говорит о том, как работает общий ptr.