shared_ptr, weak_ptr и циклические зависимости

Я думаю, что мой вопрос похож на общие_ptr и weak_ptr различия, но я интересно посмотреть, как они работают вместе, а не список различий.

Страница Википедии на shared_ptr и weak_ptr указывает, что weak_pointer можно использовать для решения проблемы циклической зависимости. , и он дает пример:

std::shared_ptr<int> p1(new int(5));
std::weak_ptr<int> wp1 = p1; //p1 owns the memory.

{
  std::shared_ptr<int> p2 = wp1.lock(); //Now p1 and p2 own the memory.
  if(p2) //Always check to see if the memory still exists
  { 
    //Do something with p2
  }
} //p2 is destroyed. Memory is owned by p1.

p1.reset(); //Memory is deleted.

std::shared_ptr<int> p3 = wp1.lock(); //Memory is gone, so we get an empty shared_ptr.
if(p3)
{
  //Will not execute this.
}

Но я не вижу циклической зависимости, поэтому не понимаю, как weak_pointer решает проблему.

Я ожидал увидеть какой-то объект a, указывающий на объект b, и b каким-то образом указывающий обратно на aweak_ptr, помещенным между одним из ребер ориентированного графа, чтобы разорвать цепочку).

Является ли пример хорошим, а мое мышление плохим? Или есть лучший пример проблемы и решения?


person jww    schedule 13.01.2014    source источник
comment
утверждают, что weak_pointer можно использовать для решения проблемы циклической зависимости, и оба утверждения совершенно неверны; слабые ссылки имеют мало применений, и циклическая зависимость не является одной из них.   -  person curiousguy    schedule 29.12.2016


Ответы (1)


В текущей версии страницы википедии пример призван продемонстрировать использование std::weak_ptr в целом, не исключая в частности сильные циклические ссылки. (Циклические ссылки упоминаются только после представления примера.)

Пример показывает, что wp1, несмотря на время своего существования, не владеет памятью, на которую указывает p1, и что wp1 правильно определяет удаление этой памяти после сброса p1. Другими словами, wp1 не препятствовала удалению динамически размещенного объекта и не вызывала неопределенного поведения, когда к удаленному объекту (правильно) обращались через слабый указатель.

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

person user4815162342    schedule 16.12.2014