Позвольте мне повторить ваш вопрос: «Мой вопрос, как циклические структуры данных делают счетчик ссылок выше нуля, просьба показать с примером в программе на C ++. Как проблема решается с помощью weak_ptrs
еще раз с примером, пожалуйста.»
Проблема возникает с кодом C ++, подобным этому (концептуально):
class A { shared_ptr<B> b; ... };
class B { shared_ptr<A> a; ... };
shared_ptr<A> x(new A); // +1
x->b = new B; // +1
x->b->a = x; // +1
// Ref count of 'x' is 2.
// Ref count of 'x->b' is 1.
// When 'x' leaves the scope, there will be a memory leak:
// 2 is decremented to 1, and so both ref counts will be 1.
// (Memory is deallocated only when ref count drops to 0)
Чтобы ответить на вторую часть вашего вопроса: для подсчета ссылок математически невозможно иметь дело с циклами. Следовательно, weak_ptr
(который в основном является просто урезанной версией shared_ptr
) не может использоваться для решения проблемы цикла - программист решает проблему цикла.
Чтобы решить эту проблему, программист должен знать о отношении владения между объектами или должен изобрести отношения владения, если такого владения не существует естественным образом.
Вышеприведенный код C ++ может быть изменен так, чтобы A владел B:
class A { shared_ptr<B> b; ... };
class B { weak_ptr<A> a; ... };
shared_ptr<A> x(new A); // +1
x->b = new B; // +1
x->b->a = x; // No +1 here
// Ref count of 'x' is 1.
// Ref count of 'x->b' is 1.
// When 'x' leaves the scope, its ref count will drop to 0.
// While destroying it, ref count of 'x->b' will drop to 0.
// So both A and B will be deallocated.
Ключевой вопрос: можно ли использовать weak_ptr
в том случае, если программист не может определить отношения владения и не может установить статическое владение из-за отсутствия привилегий или отсутствия информации?
Ответ: Если владение объектами неясно, weak_ptr
не может помочь. Если есть цикл, программист должен найти его и сломать. Альтернативное решение - использовать язык программирования с полной сборкой мусора (такой как: Java, C #, Go, Haskell) или использовать консервативный (= несовершенный) сборщик мусора, который работает с C / C ++ (такой как: Boehm GC) .