2010-08-26 2 views
2

Я сейчас в такой ситуации, как:повышение :: shared_ptr цикл разрыв с weak_ptr

struct A { 
    shared_ptr<B> b; 
}; 
struct B { 
    shared_ptr<A> a; 
}; 

//... 
shared_ptr<A> a(new A()); 
shared_ptr<B> b(new B()); 
a->b(b); 
b->a(a); 

Я знаю, это не будет работать, так как ссылки будут продолжать указывать друг на друга. Мне также сказали, что weak_ptr решает эту проблему.

Однако weak_ptr не имеет пересылки или -> перегрузки. Я слышал упоминания о «использовании lock()», но может ли кто-нибудь привести примеры кода, как это сделать правильно?

ответ

-1

Да ладно.

http://boost.org/doc/libs/1_42_0/libs/smart_ptr/weak_ptr.htm

^^^^^ ПРИМЕР ПРАВИЛЬНО ЛИ ^^^^^^

DAMN!

+7

-1 Хотя ссылки на документы полезно, SO ответы должны быть полезными для будущих посетителей должны ссылка стать мертвым. Этот ответ не содержит никакой информации, кроме ссылки. – cdhowie

+0

Плохое отношение к OP – zpon

2

Вы проверили ссылку на повышение на weak_ptr?

shared_ptr<int> p(new int(5)); 
weak_ptr<int> q(p); 

// some time later 

if(shared_ptr<int> r = q.lock()) 
{ 
    // use *r 
} 

Идея заключается в том, что вы блокируете weak_ptr тем самым получая shared_ptr, который делает у операторов.

Сначала проверьте, указывает ли полученный указатель на что-то. A weak_ptr не определяет срок службы ресурса, но позволяет проверить, был ли ресурс уже уничтожен.

-1
#include <boost/shared_ptr.hpp> 
#include <boost/weak_ptr.hpp> 

struct B; 

struct A 
{ 
    boost::weak_ptr<B> b; 
}; 

struct B 
{ 
    boost::weak_ptr<A> a; 
}; 

int 
main() 
{ 
    boost::shared_ptr<A> a(new A()); 
    boost::shared_ptr<B> b(new B()); 
    a->b = b; 
    b->a = a; 
    boost::shared_ptr<A> another_a(b->a.lock()); 
} 

вы можете способствовать созданию weak_ptr к shared_ptr с помощью weak_ptr::lock.

6

Я думаю, что более крупная проблема здесь является одной из двусмысленных форм собственности. Вам было бы лучше решить, будет ли A инкапсулировать B или наоборот. Если это невозможно, вам все равно лучше представить еще class C, которому принадлежат как A, так и B.

Предполагая, что A владеет B, вы можете написать:

classs B; 

classs A 
{ 
private: 
    boost::scoped_ptr<B> b_; 
public: 
    A() : b_(new B()) {} 
} 

class B 
{ 
private: 
    A* a_; 
public: 
    B(A* a) : a_(a) {} 
} 

И так далее. Вы можете даже избавиться от scoped_ptr, сделав B локальной переменной или удалив ее вручную в деструкторе.

Google C++ Style Guide есть что сказать об этом в разделе под названием «Smart Pointers».

НТН

+0

+1, я чуть не задохнулся, увидев, что кто-то ссылается на Руководство по стилю Google C++ ... но на этот раз я согласен с ними, четкое владение предпочтительнее, чтобы разбрызгать 'shared_ptr' здесь и там. –

+0

Спасибо за +1! Но мне интересно, как вы смотрите на руководство по стилю Google C++. Есть ли какая-то особая причина, по которой вы находите ее немного достойной? – Mhmmd

+0

+1 «Большая проблема здесь заключается в двусмысленном владении». Да; вам нужно сначала рассмотреть право собственности, и ** только когда вы понимаете отношения между вашими объектами **, вы можете использовать интеллектуальный указатель. – curiousguy

Смежные вопросы