當您使用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)
但我真的不能換我的頭周圍的影響(如果有的話),這等效可能與遞減/增加參考計數的順序有關。
因此,沒有這裏的標準指定的訂單?或者是這個實現定義的行爲?