我有以下Container
类
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;
}
};
我这样称呼它
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;
}
这是我得到的输出
useCount main pre: 1
useCount addItem pre: 2
useCount addItem post: 0
useCount main post: 2
一行一行...
有道理,一旦定义,就只有一个对
s
的引用这是有道理的,
s
被复制到item
,因此其引用计数增加 1我已经给了
items_
item
的所有权,所以引用计数不应该改变,因为addItem
已经放弃了所有权并将其转让给items_
。我希望引用计数为 2,一次来自main
,一次来自items_
.而是 0。只要一个引用来自
main
并且一个引用来自items_
就有意义。
感谢您的任何澄清!
从共享指针移出后,它应为空。空共享指针的使用计数为 0。
从另一个角度来看,你期望在这一点上,main
和items_
拥有该对象(这是正确的(,但如果它们计入指针item
的use_count
,那么总共有三个共享指针拥有该对象。这与你对 2 的期望相矛盾。当然,这是因为item
不再拥有该对象,因此它的使用计数实际上不再与拥有它的其他指针相关。
std::move
将项目从该变量移动到另一个变量中。正如一位作者所说,它"有掠夺[变量]的明确许可"。对于大多数 std 对象,这会将原始对象置于未指定的状态。但是,它似乎std:shared_ptr
是一个例外,因为它使对象处于空状态。
这一切归结为,在移动后,您不能再将item
视为对s
的相同引用。它处于不同的状态,存储其他内容。这就是您的引用计数关闭的原因。
相反,如果您这样做了:
std::cout << "useCount addItem post: " << items_.back().use_count() << std::endl;
您将获得2
的预期输出。