Мне не понравился ни один из предыдущих ответов, поэтому:
Нет, я не знаю о реализации, но я думаю, что это возможно. Стандартная реализация shared_ptr содержит два счетчика ссылок, один для «сильных» и один для «слабых» ссылок, и указатель на референт. В реализации intrusive_ptr сильный счет должен быть частью объекта, но слабый не может быть. Похоже, вы могли бы создать «слабый» intrusive_ptr.
Определить хелпер слабого указателя:
template<class X>
class intrusive_ptr_weak_helper {
long weak_ref_count;
X *target_instance;
};
Затем запишите это в объект рядом со счетчиком ссылок:
struct X {
...
intrusive_ptr_weak_helper *ref_weak_helper;
...
long ref_count;
...
};
При построении X:
ref_count = 0;
ref_weak_helper = NULL;
"Сильный" указатель, intrusive_strong_ptr, идентичен intrusive_ptr, пока не произойдет удаление. Когда счетчик сильных ссылок становится равным нулю (до удаления):
if (ref_weak_helper != NULL) {
if (ref_weak_helper->weak_ref_count == 0)
delete ref_weak_helper;
else
ref_weak_helper->target_instance = NULL;
}
«Слабая» версия, intrusive_weak_ptr, записывает указатель на слабого помощника, управляя этим счетчиком ссылок и получая доступ к целевому объекту через указатель target_instance. Когда значение weak_ref_count уменьшается до нуля, состояние target_instance определяет, был ли удален помощник.
Есть много деталей, отсутствующих (например, в отношении параллелизма), но это смешение shared_ptr и intrusive_ptr. Он поддерживает основные преимущества intrusive_ptr (оптимизация кеша, повторное использование сторонних подсчетов навязчивых (сильных) ссылок, заменители сильных и слабых указателей имеют размер указателя), в то же время добавляя дополнительную работу в основном по пути слабых ссылок.