2011-03-18 90 views
10

以下兩段代碼是否有區別?他們中的任何一個比另一個更可取?boost shared_ptr:operator =和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... 
+1

http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm#Members – DumbCoder 2011-03-18 12:20:28

回答

15

operator=shared_ptr指定爲shared_ptr,而reset指定shared_ptr取得指針的所有權。所以,你發佈的例子基本上沒有區別。這就是說,你應該更喜歡他們都沒有,只是用make_shared

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

另外,如果可能的話,你可以防止不必聲明shared_ptr沒有初始化通過一個單獨的函數包裹在try-catch塊只是返回一個shared_ptr到新創建的對象:

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

能否請您證明您的評論說make_shared應該是首選? – Jon 2013-03-14 20:01:07

+0

使用'new'構建對象並使用它初始化'shared_ptr'是一個兩步過程。理論上,創建對象可能會成功,但初始化'shared_ptr'可能會失敗,在這種情況下,您會泄漏內存,除非您明確處理該情況。 'make_shared'照顧你。根據[文檔](http://www.boost.org/doc/libs/release/libs/smart_ptr/make_shared.html),它也更快。 – 2013-03-14 20:10:37

3

operator=另需shared_ptr作爲從而參數創建另一個副本(和加大了基準計),而reset()需要一個指針和任選的刪除器,從而在現實中創建一個新的sh ared_ptr在當前的頂部。

復位等同於(而且很可能爲實現)

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; 
} 

的兩個功能是類似的,它們釋放的他們是什麼控制已經包含(如果有的話)並管理不同的指針。

+1

'reset'也被重載以獲取另一個共享指針,在這種情況下,它相當於賦值。 – 2011-03-18 12:42:16

+0

CashCow:你可以在你的'operator ='實現中解釋'shared_ptr shared(other)'這一行的作用嗎? – freitass 2013-06-07 11:48:30

2

foo.reset(p)被定義爲等同於shared_ptr(p).swap(foo)

賦值在邏輯上等同於複製和交換,並且可能以這種方式實現。所以foo = shared_ptr(p);相當於foo.swap(shared_ptr(p))。如果編譯器的日子非常糟糕,那麼可能還會有一個額外的副本。

所以在你給的例子中,我不認爲他們之間有很多選擇。可能還有其他重要的情況。但是,reset對模板構造函數所執行的靜態類型p執行相同的基於模板的捕獲,因此,就獲得正確的刪除器而言,您會被覆蓋。

轉讓的主要用途是當您要複製以前存在的shared_ptr以共享同一對象的所有權。當然,它也可以在臨時分配時正常工作,並且如果您查看不同的重載,它們會鏡像不同的構造函數。所以我懷疑你可以以任何方式達到同樣的目的。附加到新的底層 -

0

賦值運算符從一個現有,遞增引用計數

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; 
} 

在復位呼叫不創建新的共享對象,而是一個新的所有權創建新的共享對象指針對象(通過控制對象)

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); 
} 
相關問題