我有一个shared_ptrs向量,如下所示。
std::vector<std::shared_ptr<SharedThing>> things;
现在让我说我将一些shared_ptrs推送到向量上,每个元素现在的引用计数为1.
当我需要用新的shared_ptr替换其中一个元素时,我希望旧的shared_ptr超出范围。常规元素赋值是否会实现,或者只是复制shared_ptr内容。例如:
things.at(0) = new_shared_ptr;
这会减少things.at(0)的引用计数并增加new_shared_ptr的计数吗?
答案 0 :(得分:3)
当我需要用新的shared_ptr替换其中一个元素时 希望旧的shared_ptr超出范围。将常规元素 任务实现这个?
向量中的共享指针不会超出范围,
但它会用给定的新对象替换托管对象。
致电:
things.at(0) = new_shared_ptr;
将计数保留为1.
以下是观察此行为的简便方法:
#include <iostream>
#include <vector>
#include <memory>
int main(){
//vector with a shared pointer
std::vector<std::shared_ptr<int>> things;
things.push_back(std::make_shared<int>(1));
//prints 1
std::cout << things.at(0).use_count() << '\n';
//assign a new value
things.at(0) = std::make_shared<int>(2);
//still prints 1
std::cout << things.at(0).use_count() << '\n';
}
虽然不是您问题的一部分,但通常建议您使用make_shared
代替new
。
答案 1 :(得分:2)
是的,基本上你是对的。
为了更准确,将减少(0)处的先前shared_ptr的引用计数。然后你给它分配一个新的shared_ptr,它可能有计数1.看起来(0)的引用计数是相同的,但它改变了并且改回来了。
您可以通过std :: shared_ptr :: use_cout()
进行验证有关详细信息,我们可以在调试时调试到STL
things.at(0) = new_shared_ptr;
包括/ C ++ / 4.8.3 /比特/ shared_ptr_base.h:556
__shared_count&
operator=(const __shared_count& __r) noexcept
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != _M_pi)
{
if (__tmp != 0)
__tmp->_M_add_ref_copy();
if (_M_pi != 0)
_M_pi->_M_release();
_M_pi = __tmp;
}
return *this;
}
新的_M_add_ref_copy(),然后是前一个_M_release(),它会将_M_use_count减少1。