On Thu, Jan 5, 2017 at 11:54 PM, Jared Grubb
El ene. 5, 2017, a las 10:02, Roberto Hinz
escribió: Suppose an object A has a shared_ptr to an object B which has a weak_ptr to A. Every time this weak_ptr is used, it may not be eligible anymore to originate a non null shared_ptr. In this case, if B can nicely handle this locally ( checking the result of weak_ptr
::lock() ), then fine. But if it can't, is has to throw an exception. And this can be highly undesirable. One way to solve this problem would turn B a member object of A, or manage B with a unique_ptr owned by A. This way we ensure that A is never destroyed before B. But suppose that for some reason, there is something that requires a shared_ptr to B. How do you solve that? For this exact scenario, you can use the aliasing constructor of shared_ptr (for reference, see constructor #8 on http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr < http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr>):
class A : public std::enable_shared_from_this<A> { // ... protected: std::shared_ptr<B> make_B_handle() const { return std::shared_ptr<B>{ shared_from_this(), b_.get() }; } private: std::unique_ptr<B> b_; };
The aliasing constructor says roughly that "I know that the pointer I'm giving you (the B* in this case) is valid if and only if the shared_ptr<A> is valid". You could even have the B directly in the A instead of via a unique_ptr (and then you give &b_ instead of b_.get()).
Well, that's a bit embarrassing, but I have to admit my ignorance now. If I knew this aliasing constructor of shared_ptr before, I wouldn't have elaborated shared_handle. It seems that the only remaining benefit of shared_ptr is that it can be used to impose the use make_shared or allocate_shared, which in turn ensures that a shared_ptr can aways be instantiated, including in the constructor. But this doesn't seem appealing enough. So lets drop the idea for now. Thank you all for the replies, Best regards Roberto