Ненавязчивая реализация общего указателя обычно содержит указатель на некоторое динамически распределяемое «состояние», которое подсчитывает, сколько ссылок существует на исходный объект.
Когда копируется общий указатель, копия получаеттот же указатель на то же самое «состояние», и счетчик внутри «состояния» увеличивается , указывая, что теперь есть два общих указателя, совместно использующих ресурс.
Когда общий указатель уничтожен, уменьшает счетчик, чтобы указать, что теперь ресурс, совместно использующий ресурс, на один меньше.Если это приводит к нулевому показанию счетчика, ресурс уничтожается.
Слабый указатель также имеет указатель на это «состояние», но он не увеличивает или уменьшает счетчик.Когда его спросят, он создаст общий указатель, используя то же состояние, но только если счетчик не равен нулю.Если счетчик равен нулю, последний общий указатель уже уничтожил ресурс, и мы больше не можем получить к нему доступ.
Интересно то, что вам также нужна такая логика, чтобы контролировать время жизни "государственный "объект.:) (я бы предположил, что это реализовано с использованием второго счетчика, который shared_ptr
и weak_ptr
делает приращение, но не цитируйте меня об этом.)
(your data) (ref. counters)
║ ║
[resource] [state]
┆ │ │ │ │ │
┆ │ └─[shared_ptr]───┘ │ │
┆ └───[shared_ptr]─────┘ │
└┄┄┄┄┄┄┄[weak_ptr]────────┘
Конечно, то, как именно выглядит закрытый раздел любой конкретной реализации std::weak_ptr
, зависит от того, кто его написал.
Кстати, диаграмма показывает, почему вы не должны создавать shared_ptr
из необработанного указателя, если вы подозреваете, что ресурс, на который он указывает, может уже управляться shared_ptr
в другом месте: вы получите второй, не связанный с ним объект "состояние", ваши счетчики будутневерно, и ваш ресурс может быть преждевременно уничтожен (и определенно будет уничтожен дважды, если такое понятие существует), что может привести к хаосу.