Boost logo

Boost :

Subject: Re: [boost] [SmartPtr] alternative to enable_shared_from_this
From: Roberto Hinz (robhz786_at_[hidden])
Date: 2017-01-06 06:47:29


On Thu, Jan 5, 2017 at 11:54 PM, Jared Grubb <jared.grubb_at_[hidden]> wrote:

>
> > El ene. 5, 2017, a las 10:02, Roberto Hinz <robhz786_at_[hidden]>
> 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<A_type>::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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk