
Сергей Ильин wrote:
Let’s add this code into the weak_ptr:
shared_ptr<element_type> operator-> () const // throws bad_weak_ptr when expired { shared_ptr<element_type> temp = lock(); if( !temp ) boost::throw_exception( boost::bad_weak_ptr() ); return temp; }
New way of use weak_ptr: shared_ptr< MyClass > sp( new MyClass ); weak_ptr< MyClass > wp(sp); try { wp->Use1(); wp->Use2(); } catch( const exception& e ) { cout << e.what() << endl; }
It seems to me, that my way is more convenient than old school:
if(shared_ptr<MyClass> temp = wp.lock()) { temp->Use1(); temp->Use2(); } else cout << "Cannot use, already destroyed" << endl ;
The two have different semantics - the first can execute Use1 but then throw due to the pointee being destroyed before the call to Use2, whereas the second version either calls both or neither. In addition, this change encourages poor code (such as your example), where multiple shared_ptrs are created unnecessarily, and exceptions can occur at arbitrary points in a sequence of calls. Finally, a weak_ptr not being available isn't really an exceptional circumstance, and if you really want to avoid the if, you can write something like: template <class T> shared_ptr<T> throw_lock(weak_ptr<T> const& p) { shared_ptr<T> temp(p); if(!temp) boost::throw_exception(boost::bad_weak_ptr()); return temp; } then do: throw_lock(wp)->Use1(); throw_lock(wp)->Use2(); At least the problems are explicit in that version. All that said, operator-> might be a useful convenience for the case where you are making only a single call, or you don't care about exceptions or efficiency, but the problem is that people may start to use it in all cases. Tom