When swapping the content of two shared_ptr
s, only the contents are swapped. When there is a shared_ptr
created from the other one before the swap, I am surprised that the content of the new shared_ptr
copy remains the same.
Here is an example:
std::shared_ptr<int> foo (new int(10));
std::shared_ptr<int> bar (new int(20));
auto abc = foo;
std::swap (foo, bar);
std::cout << "foo: " << *foo << '\n';
std::cout << "bar: " << *bar << '\n';
std::cout << "abc: " << *abc << '\n';
It prints:
foo: 20
bar: 10
abc: 10
Why is abc
not 20 in this case? Given that it's a copy of foo
.
shared_ptr
is just a pointer to data. You are not swapping the data itself, you are swapping the pointers.
Lets look at it step-by-step:
std::shared_ptr<int> foo (new int(10)); std::shared_ptr<int> bar (new int(20));
After these statements, you have two pointers to two separate allocated int
s:
[ foo ] ---> [10]
[ bar ] ---> [20]
auto abc = foo;
This statement then creates abc
to point at the same allocated int
that foo
is pointing at. So, before the swap, you now have:
[ foo ] -+-> [10]
|
[ abc ] -+
[ bar ] ---> [20]
std::swap (foo, bar);
Then, you are swapping the pointers that foo
and bar
are holding, but you are leaving the pointer in abc
alone. So, after the swap, you now have:
+---------------+
| |
[ foo ] +-> [10] |
| |
[ abc ] -+ |
| |
[ bar ] -+ [20] <-+
That is why *foo
prints 20, *bar
prints 10, and *abc
prints 10.