I have the following Container
class
template <typename T>
class Container
{
private:
std::vector<std::shared_ptr<T>> items_;
public:
void addItem(std::shared_ptr<T> item)
{
std::cout << "useCount addItem pre: " << item.use_count() << std::endl;
items_.push_back(std::move(item));
std::cout << "useCount addItem post: " << item.use_count() << std::endl;
}
};
and I'm calling it like this
int main(int argc, char** argv) {
std::unique_ptr<Container<std::string>> container = std::make_unique<Container<std::string>>();
std::shared_ptr<std::string> s = std::make_shared<std::string>("hello");
std::cout << "useCount main pre: " << s.use_count() << std::endl;
container->addItem(s);
std::cout << "useCount main post: " << s.use_count() << std::endl;
return 0;
}
This is the output I get
useCount main pre: 1
useCount addItem pre: 2
useCount addItem post: 0
useCount main post: 2
Line by line...
Makes sense, there's only one reference to s
as soon as its defined
Makes sense, s
gets copied into item
so its reference count is incremented by 1
I've given items_
ownership of item
, so the reference count shouldn't change since addItem
has relinquished ownership and transferred it to items_
. I expect the reference count to be 2, once from main
and once from items_
. Instead it's 0.
Makes sense as long as one reference is from main
and one reference is from items_
.
Thanks for any clarification!
std::move
moves the item out of that variable into another one. As one author put it, it "has explicit license to pillage [the variable]." For most std objects, that puts the original object into an unspecified state. However, it appears std:shared_ptr
is an exception in that it leaves the object in an empty state.
What all this boils down to is that you can't treat item
as the same reference to s
anymore after the move. It is in a different state, storing something else. That's why your reference count is off.
If instead you had done this:
std::cout << "useCount addItem post: " << items_.back().use_count() << std::endl;
You would have got the expected output of 2
.