簡體   English   中英

提高shared_ptr:運算符=和重置之間的區別?

[英]boost shared_ptr: difference between operator= and reset?

下面的兩段代碼之間有什么區別嗎? 他們中的任何一個比另一個更可取嗎?

運算符=

boost::shared_ptr<Blah> foo; // foo.ptr should be NULL
foo = boost::shared_ptr<Blah>(new Blah()); // Involves creation and copy of a shared_ptr?

重啟

boost::shared_ptr<Blah> foo; // foo.ptr should be NULL
foo.reset(new Blah()); // foo.ptr should point now to a new Blah object

注意:我需要定義shared_ptr,然后將其設置在另一行中,因為我在一段代碼中使用它,例如:

boost::shared_ptr<Blah> foo;
try
{
  foo.reset...
}
foo...

operator=shared_ptr分配給shared_ptr ,而reset使shared_ptr擁有指針的所有權。 因此,您發布的示例之間基本上沒有區別。 就是說,您不應該選擇其中任何一個,而只需使用make_shared

foo = boost::make_shared<Blah>();

另外,如果可能的話,可以通過將try-catch塊包裝在一個單獨的函數中來避免在不進行初始化的情況下聲明shared_ptr ,該函數只需將shared_ptr返回到新創建的對象:

boost::shared_ptr<Blah> createBlah() {
    try {
        // do stuff
        return newBlah;
    }
    catch ...
}

operator=將另一個shared_ptr作為參數,從而創建另一個副本(並增加引用計數),而reset()獲取一個指針和一個可選的刪除器,從而實際上在當前副本的頂部創建一個新的shared_ptr。

reset等效於(並且可能實現為)

void reset(T p, D d)
{
   shared_ptr shared(p,d);
   swap( shared );
}

operator=可能實現為:

shared_ptr& operator=( shared_ptr const& other )
{
   shared_ptr shared(other);
   swap(other);
   return *this;
}

這兩個函數的相似之處在於,它們釋放對它們已經包含的內容的控制(如果有的話),而是管理一個不同的指針。

foo.reset(p)定義為與shared_ptr(p).swap(foo)等效。

分配在邏輯上等效於復制和交換,並且可能以這種方式實現。 所以foo = shared_ptr(p); 等效於foo.swap(shared_ptr(p)) 如果編譯器的日子很不好,可能在其中有一個額外的副本。

因此,在您提供的示例中,我認為它們之間沒有太多選擇。 可能還有其他情況很重要。 但是reset與模板構造函數所做的相同,是基於模板的靜態類型p的基於模板的捕獲,因此就獲得正確的刪除器而言,您已經了解了。

分配的主要用途是當您要復制先前存在的shared_ptr ,以共享同一對象的所有權時。 當然,從臨時分配時也可以正常工作,如果您查看不同的reset重載,它們將反映不同的構造函數。 因此,我懷疑您可以通過任何一種方式實現相同的目標。

賦值運算符從現有對象創建一個新的共享對象,從而增加引用計數

CSharedObj& CSharedObj::operator=(CSharedObj& r) noexcept
{ 
     if(*this != r){
        //detach from the previous ownership
        if(0 == dec()) delete m_pControlObj;
        //attach to the new control object and increment the reference count
        r.inc();
        m_pControlObj = r.m_pControlObj;
    }
    return *this;
}

而reset調用不會創建新的共享庫,而是創建新的所有權-附加到新的基礎pointee(通過控制對象)

void CSharedObj::reset(Ptr pointee) noexcept
{
   //check if this is a last reference-detach from the previous ownership
   if(0==dec()) delete m_pControlObj;
   // create the ownership over the new pointee (refCnt = 1)
   m_pControlObj = new (std::nothrow) CControlObj(pointee);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM