当您使用shared_ptr
的复制分配操作符时,概念上,分配左侧的shared_ptr
需要递减当前拥有的对象的引用计数,然后递增分配右侧对象的引用计数。 (假设,当然,这两个指针非空。)shared_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;
}
但需要注意的是,这里我们递减的this
引用计数之前我们增加了参考计数rhs
。我们也可以通过其他方式来做到这一点。我的问题是,标准是否确实在这里指定了顺序?
为什么它的确与众不同:它可以使在事件大差异有某种this
引用计数和lhs
引用计数之间的相关性。例如,假设两者都是链接列表结构的一部分,其中每个链接节点中的next
指针为shared_ptr
。因此,递减结构中任何节点的引用计数可能会触发析构函数,然后析构函数会引发连锁反应并减少链中每个其他节点的引用计数(并可能会破坏)。
那么,假设其中lhs
引用计数是由this
引用计数安全的情况下,它使一个很大的区别,如果我们第一递减this
,或者我们首先增加lhs
。如果我们首先增加lhs
之前递减this
,那么我们可以确定lhs
不会在我们递减this
时被销毁。
但这是否标准实际上在这里指定的顺序?据我所看到的,标准说的唯一的事情是,拷贝赋值运算符是等效于表达式:
shared_ptr(lhs).swap(*this)
但我真的不能换我的头周围的影响(如果有的话),这等效可能与递减/增加参考计数的顺序有关。
因此,没有这里的标准指定的订单?或者是这个实现定义的行为?