了解传递给函数时 shared_ptr 引用计数何时递增
Understanding when shared_ptr reference counts are incremented when passing into a function
我有以下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;
}
};
我是这样称呼它的
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
我已将 item
的所有权授予 items_
,因此引用计数不应更改,因为 addItem
已放弃所有权并将其转让给 items_
。我希望引用计数为 2,一次来自 main
,一次来自 items_
。相反它是 0.
有意义,只要一个引用来自 main
,一个引用来自 items_
。
感谢您的澄清!
移动共享指针后,它应该是空的。空共享指针的使用次数为0.
从另一个角度来看,您期望 main
和 items_
拥有该对象(这是正确的),但如果将它们计入 use_count
的指针 item
,则共有三个共享指针拥有该对象。这与您对 2 的期望相矛盾。当然,这可以通过 item
不再拥有该对象这一事实来解释,因此它的使用计数实际上不再与拥有它的其他指针相关。
std::move
将项目从那个变量移到另一个变量中。正如一位作者所说,它“has explicit license to pillage [the variable]." For , that puts the original object into an unspecified state. However, it appears 因为它使对象处于空状态。
所有这一切归结为您不能再将 item
视为对 s
的相同引用。它处于不同的状态,存储着别的东西。这就是您的引用计数关闭的原因。
如果你这样做了:
std::cout << "useCount addItem post: " << items_.back().use_count() << std::endl;
您将获得 2
的预期输出。
我有以下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;
}
};
我是这样称呼它的
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我已将
item
的所有权授予items_
,因此引用计数不应更改,因为addItem
已放弃所有权并将其转让给items_
。我希望引用计数为 2,一次来自main
,一次来自items_
。相反它是 0.有意义,只要一个引用来自
main
,一个引用来自items_
。
感谢您的澄清!
移动共享指针后,它应该是空的。空共享指针的使用次数为0.
从另一个角度来看,您期望 main
和 items_
拥有该对象(这是正确的),但如果将它们计入 use_count
的指针 item
,则共有三个共享指针拥有该对象。这与您对 2 的期望相矛盾。当然,这可以通过 item
不再拥有该对象这一事实来解释,因此它的使用计数实际上不再与拥有它的其他指针相关。
std::move
将项目从那个变量移到另一个变量中。正如一位作者所说,它“has explicit license to pillage [the variable]." For
所有这一切归结为您不能再将 item
视为对 s
的相同引用。它处于不同的状态,存储着别的东西。这就是您的引用计数关闭的原因。
如果你这样做了:
std::cout << "useCount addItem post: " << items_.back().use_count() << std::endl;
您将获得 2
的预期输出。