Reputation: 635
I have a vector of shared_ptrs as below.
std::vector<std::shared_ptr<SharedThing>> things;
Now let's say I push a number of shared_ptrs onto the vector and each element now has a reference count of 1.
When I need to replace one of those elements with a new shared_ptr I want the old shared_ptr to go out of scope. Will regular element assignment achieve this or will it just copy the shared_ptr contents. For example:
things.at(0) = new_shared_ptr;
Will this decrement the reference count of things.at(0) and increment the count of new_shared_ptr?
Upvotes: 3
Views: 2356
Reputation: 513
Yes, basically you are right.
To be more accurate, the reference count of previous shared_ptr at(0) will be decremented. And then you assign it with a new shared_ptr, which may have the count 1. Looks like the reference count at(0) is the same, but it changed and changed back.
You can verify it by std::shared_ptr::use_cout()
For more details, we can debug into the STL, when
things.at(0) = new_shared_ptr;
include/c++/4.8.3/bits/shared_ptr_base.h:556
__shared_count&
operator=(const __shared_count& __r) noexcept
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != _M_pi)
{
if (__tmp != 0)
__tmp->_M_add_ref_copy();
if (_M_pi != 0)
_M_pi->_M_release();
_M_pi = __tmp;
}
return *this;
}
The new one _M_add_ref_copy(), then previous one _M_release(), which will decrease the _M_use_count by 1.
Upvotes: 2
Reputation: 37806
When I need to replace one of those elements with a new shared_ptr I want the old shared_ptr to go out of scope. Will regular element assignment achieve this?
The shared pointer in the vector won't go out of scope,
but it will replace the managed object with the new one given.
Calling:
things.at(0) = new_shared_ptr;
will preserve the count at 1.
Here is an easy way to observe this behaviour:
#include <iostream>
#include <vector>
#include <memory>
int main(){
//vector with a shared pointer
std::vector<std::shared_ptr<int>> things;
things.push_back(std::make_shared<int>(1));
//prints 1
std::cout << things.at(0).use_count() << '\n';
//assign a new value
things.at(0) = std::make_shared<int>(2);
//still prints 1
std::cout << things.at(0).use_count() << '\n';
}
Although not a part of your question, it is often advised to use make_shared
instead of a new
.
Upvotes: 3