C++ 共享ptr分配:引用计数顺序

C++ 共享ptr分配:引用计数顺序,c++,c++11,shared-ptr,C++,C++11,Shared Ptr,使用共享\u ptr的复制分配运算符时,从概念上讲,分配左侧的共享\u ptr需要减少其当前拥有的对象的引用计数,然后增加分配右侧的对象引用计数。(当然,假设两个指针都是非空的。) 因此,实现可能类似于以下伪代码: shared_ptr& operator = (const shared_ptr& rhs) { decrement_reference_count(this->m_ptr); this->m_ptr = rhs.m_ptr; incre

使用
共享\u ptr
的复制分配运算符时,从概念上讲,分配左侧的
共享\u ptr
需要减少其当前拥有的对象的引用计数,然后增加分配右侧的对象引用计数。(当然,假设两个指针都是非空的。)

因此,实现可能类似于以下伪代码:

shared_ptr& operator = (const shared_ptr& rhs)
{
   decrement_reference_count(this->m_ptr);
   this->m_ptr = rhs.m_ptr;
   increment_reference_count(this->m_ptr);
   return *this;
}
但请注意,这里我们先减少
的参考计数,然后增加
rhs
的参考计数。我们也可以反过来做。我的问题是,标准是否在这里规定了顺序

为什么会产生差异:如果
this
的引用计数与
lhs
的引用计数之间存在某种依赖关系,则可能会产生很大的差异。例如,假设两者都是链表结构的一部分,其中每个链接节点中的
next
指针是一个
shared\u ptr
。因此,减少结构中任何节点的引用计数都可能触发析构函数,然后引发连锁反应,并在链中每隔一个节点减少引用计数(也可能是析构函数)

因此,假设
lhs
的参考计数受
this
的参考计数的影响,如果我们首先减少
this
,或者首先增加
lhs
,就会产生很大的不同。如果我们先递增
lhs
再递减
this
,那么我们可以确保
lhs
在递减
this
时不会被破坏

但该标准是否在此处指定了订单?据我所见,标准中唯一规定的是复制赋值运算符等效于表达式:

shared_ptr(lhs).swap(*this)
但是我真的不能完全理解这种等价性在减少/增加引用计数的顺序方面可能产生的影响(如果有的话)


那么,标准是否在此指定了顺序?或者此实现是定义的行为?

如果
rhs
,则必须首先递增参考计数器。否则,当引用计数器为1时,它可能会无意中破坏指针对象。它可以检查是否
this==&rhs
,但如果参考计数器增量在减量之前执行,则不需要进行此检查


shared\u ptr(lhs).swap(*this)
不会出现此问题,因为它首先创建一个副本,从而首先增加参考计数器。

如果
rhs
,则必须首先增加参考计数器。否则,当引用计数器为1时,它可能会无意中破坏指针对象。它可以检查是否
this==&rhs
,但如果参考计数器增量在减量之前执行,则不需要进行此检查


shared_ptr(lhs).swap(*this)
不会出现此问题,因为它首先创建一个副本,从而首先增加参考计数器。

标准规定[20.7.2.2.3]

shared_ptr& operator=(const shared_ptr& r) noexcept;
效果相当于

shared_ptr(r).swap(*this)

这意味着构造一个临时变量,增加
r
的引用计数,然后将其数据与
*This
交换,然后销毁该临时变量,这意味着减少以前属于
*This

的引用计数。该标准指出[20.7.2.2.3]

shared_ptr& operator=(const shared_ptr& r) noexcept;
效果相当于

shared_ptr(r).swap(*this)
这意味着构造一个临时变量,增加
r
的引用计数,然后将其数据与
*This
交换,然后销毁临时变量,这意味着减少以前属于
*This
的引用计数