Я пытался с циклическими ссылками для boost::shared_ptr
и разработал следующий образец:
class A{ // Trivial class
public:
i32 i;
A(){}
A(i32 a):i(a){}
~A(){
cout<<"~A : "<<i<<endl;
}
};
shared_ptr<A> changeI(shared_ptr<A> s){
s->i++;
cout<<s.use_count()<<'\n';
return s;
}
int main() {
shared_ptr<A> p1 = make_shared<A>(3);
shared_ptr<A> p2 = p1;
shared_ptr<A> p3 = p2;
shared_ptr<A> p4 = p3;
p1 = p4; // 1) 1st cyclic ref.
cout<<p1.use_count()<<'\n';
p1 = changeI(p4); // 2) 2nd cyclic ref.
cout<<p1.use_count()<<'\n';
// putchar('\n');
cout<<endl;
}
какие выводы
4
5
4
~A : 4
Это то, что я неверно истолковал циклические ссылки, упомянутые для boost::shared_ptr
? Потому что я ожидал другого выхода, думая о косвенных ссылках на p1
после комментариев 1)
а также 2)
,
Так что этот код не требует boost::weak_ptr
! Так, каковы циклические ссылки, где weak_ptr
s потребуется?
Заранее спасибо.
Да, вы неправильно это поняли. В вашем примере все указатели указывают на один и тот же объект, не образуя никаких циклов.
Присвоение p4 p2 является недопустимым, так как эти указатели уже были равны с самого начала.
Вот пример с реальными циклическими ссылками, может быть, это прояснит ситуацию:
struct A
{
std::shared_ptr<A> ptr;
};
void main()
{
std::shared_ptr<A> x=std::make_shared<A>();
std::shared_ptr<A> y=std::make_shared<A>();
x->ptr = y; // not quite a cycle yet
y->ptr = x; // now we got a cycle x keeps y alive and y keeps x alive
}
Вы даже можете сделать это еще проще:
void main()
{
std::shared_ptr<A> x=std::make_shared<A>();
x->ptr = x; // never die! x keeps itself alive
}
В обоих примерах объекты в shared_ptrs никогда не уничтожаются, даже после выхода из main.
Просто хотел бы указать: причина, по которой вторая строка вывода 5
и не 4
не из-за s->i++
увеличиваться, но потому что shared_ptr<A> s
параметр передается по значению.
По вызову
p1 = changeI(p4); // 2) 2nd cyclic ref.
p4
будет скопирован в еще один shared_pointer
временно увеличивая use_count
по одному во время действия функции.
Может быть, я играю здесь, очевидно, в капитана (;