替换 std::vector 中的 shared_ptr 个元素
Replacing shared_ptr elements in std::vector
我有一个 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 的计数吗?
When I need to replace one of those elements with a new shared_ptr I
want the old shared_ptr to go out of scope. Will regular element
assignment achieve this?
向量中的共享指针不会超出范围,
但它将用给定的新对象替换托管对象。
呼叫:
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
。
是的,基本上你是对的。
更准确的说,前一个shared_ptr at(0) 的引用计数会被递减。然后你给它分配一个新的shared_ptr,它的计数可能是1。看起来(0)处的引用计数是一样的,但它变了又变回来了。
可以通过std::shared_ptr::use_cout()
验证
更多细节,我们可以调试到STL中,当
things.at(0) = new_shared_ptr;
include/c++/4.8.3/bits/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。
我有一个 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 的计数吗?
When I need to replace one of those elements with a new shared_ptr I want the old shared_ptr to go out of scope. Will regular element assignment achieve this?
向量中的共享指针不会超出范围,
但它将用给定的新对象替换托管对象。
呼叫:
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
。
是的,基本上你是对的。
更准确的说,前一个shared_ptr at(0) 的引用计数会被递减。然后你给它分配一个新的shared_ptr,它的计数可能是1。看起来(0)处的引用计数是一样的,但它变了又变回来了。
可以通过std::shared_ptr::use_cout()
验证更多细节,我们可以调试到STL中,当
things.at(0) = new_shared_ptr;
include/c++/4.8.3/bits/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。