Search code examples
c++boostshared-ptrswap

Why shared pointer assignment does 'swap'?


As i understand when assigned shared ptr should behave like:

a) if (--this->count == 0) { release this->count and this->obj }

b) this->count = r->count, this->obj = r->obj;

What boost does is just

shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
{
    this_type(r).swap(*this);
    return *this;
}

So what is the magic behind swap and why this works?


Solution

  • a) if (--this->count == 0) { release this->count and this->obj }

    No, a shared_ptr keeps two counts, one for the object and one for the control block containing the reference counts. You release this->obj when the first one reaches zero and releases this->count (and the second count) when the second one reaches zero.

    b) this->count = r->count, this->obj = r->obj;

    No, you're missing a reference count increment. Also, as Yakk's answer points out, you must either check for self-assignment or increment the right side first, to avoid incorrectly destroying the object on self-assignment.

    So your understanding is incomplete/incorrect, but if you follow through the Boost code you'll see it does exactly the right thing. It increases the reference count on the r object, exchanges all the necessary values, then decreases the reference count on the original value of *this.

    The step of increasing the reference count is already implemented in the copy constructor, so it re-uses that.

    The step of exchanging all the necessary values is already implemented in the swap member, so it uses that.

    The step of decreasing the reference counts (and freeing anything if required) is already done by the destructor, so it uses that.

    This is excellent code re-use. The alternative would be to repeat all the same code as is found in the copy constructor, swap member and destructor, which would be redundant and error-prone.