了解shared_ptr传入函数时引用计数何时递增



我有以下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

一行一行...

  1. 有道理,一旦定义,就只有一个对s的引用

  2. 这是有道理的,s被复制到item,因此其引用计数增加 1

  3. 我已经给了items_item的所有权,所以引用计数不应该改变,因为addItem已经放弃了所有权并将其转让给items_。我希望引用计数为 2,一次来自main,一次来自items_.而是 0。

  4. 只要一个引用来自main并且一个引用来自items_就有意义。

感谢您的任何澄清!

从共享指针移出后,它应为空。空共享指针的使用计数为 0。

从另一个角度来看,你期望在这一点上,mainitems_拥有该对象(这是正确的(,但如果它们计入指针itemuse_count,那么总共有三个共享指针拥有该对象。这与你对 2 的期望相矛盾。当然,这是因为item不再拥有该对象,因此它的使用计数实际上不再与拥有它的其他指针相关。

std::move

将项目从该变量移动到另一个变量中。正如一位作者所说,它"有掠夺[变量]的明确许可"。对于大多数 std 对象,这会将原始对象置于未指定的状态。但是,它似乎std:shared_ptr是一个例外,因为它使对象处于空状态。

这一切归结为,在移动后,您不能再将item视为对s的相同引用。它处于不同的状态,存储其他内容。这就是您的引用计数关闭的原因。

相反,如果您这样做了:

std::cout << "useCount addItem post: " << items_.back().use_count() << std::endl;

您将获得2的预期输出。

相关内容

  • 没有找到相关文章

最新更新