Search code examples
c++c++11smart-pointersglibgtkmm

Reassigning Smart Pointers


Generally speaking do smart pointers such as std::unique_ptr and Glib::RefPtr delete their object when reassigned to point at another object, given they are the only pointers holding that given object (obviously implied in case of std::unique_ptr)?


Solution

  • For unique_ptr::reset, [unique.ptr.single.modifiers]/4:

    Effects: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not equal to nullptr, calls get_deleter()(old_p).

    Or the move assignment operator, operator=(unique_ptr&& u) in [unique.ptr.single.asgn]/2:

    Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_deleter() = std::forward<D>(u.get_deleter()).

    (Equivalent for the other assignment operator template)


    For shared_ptr, reassignment is a little bit different. shared_ptr will never destroy a referenced object when it's not the last remaining one owning it, so let's assume that is given.
    shared_ptr::reset(Y*) specifies in [util.smartptr.shared.mod]/3:

    Effects: Equivalent to shared_ptr(p).swap(*this).

    But clearly the temporary gets destroyed at the end of the function call, destroying the hold object (if applicable).
    That is the same behavior operator=(shared_ptr<> const&) has, [util.smartptr.shared.assign]/1 and 4:

    Effects: Equivalent to shared_ptr(r).swap(*this).

    … move assignment operator (template), r is shared_ptr<>&&:

    Effects: Equivalent to shared_ptr(std::move(r)).swap(*this).

    If *this was the last owning the object, then now the temporary is - which will be destroyed inside.


    For Glib::RefPtr the scenario is similar to shared_ptr: The copy assignment operator (and an assignment operator template) are defined with the same semantics. If the current RefPtr is assigned to something else, the currently hold objects reference counter is decremented and its destroyed if the resulting counter value is zero.