2011-03-18 6 views
10

क्या नीचे दिए गए कोड के दो टुकड़ों के बीच कोई अंतर है? क्या उनमें से कोई दूसरे के लिए बेहतर है?बूस्ट shared_ptr: ऑपरेटर = और रीसेट के बीच अंतर?

ऑपरेटर =

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

उत्तर

15

operator=shared_ptr को shared_ptr पर असाइन करता है, जबकि resetshared_ptr पॉइंटर का स्वामित्व लेता है। इसलिए, मूल रूप से आपके द्वारा पोस्ट किए गए उदाहरणों के बीच कोई अंतर नहीं है। जैसा कि कहा गया है, तो आप उनमें से कोई भी पसंद किए जाने वाले और बस का उपयोग make_shared:

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

इसके अलावा, अगर संभव हो तो, आप प्रारंभ के बिना एक shared_ptr घोषित करने के लिए हो रही एक अलग समारोह में कोशिश कैच ब्लॉक लपेटकर द्वारा रोका जा सकता है कि बस रिटर्न नव निर्मित वस्तु के लिए एक shared_ptr:

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

आप अपनी टिप्पणी कि make_shared प्राथमिकता दी जानी चाहिए औचित्य साबित सकते हैं? – Jon

+0

'new' का उपयोग करके ऑब्जेक्ट पर बिल्डिंग और इसके साथ 'shared_ptr' प्रारंभ करना दो-चरणीय प्रक्रिया है। सिद्धांत रूप में, ऑब्जेक्ट बनाना सफल हो सकता है, लेकिन 'shared_ptr' को प्रारंभ करना विफल हो सकता है, इस स्थिति में आप स्मृति को रिसाव करेंगे, जब तक कि आप उस मामले को स्पष्ट रूप से संभाल नहीं लेते। 'make_shared' आपके लिए इसका ख्याल रखता है। [प्रलेखन] के अनुसार (http://www.boost.org/doc/libs/release/libs/smart_ptr/make_shared.html), यह भी तेज़ है। –

3

operator= एक और shared_ptr एक पैरामीटर इस प्रकार एक और प्रतिलिपि बनाने (और संदर्भ गिनती बढ़ाने) reset() एक सूचक और वैकल्पिक रूप से एक Deleter लेता है के रूप में, इस प्रकार वास्तव में एक नया श बनाने लेता है मौजूदा एक के शीर्ष पर ared_ptr।

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

दो कार्यों कि में समान हैं वे वे क्या कर रहे हैं के नियंत्रण जारी:

रीसेट के बराबर (और शायद के रूप में लागू)

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

operator= के रूप में लागू होने की संभावना है है पहले से ही, यदि कोई है, और इसके बजाय एक अलग सूचक का प्रबंधन।

+1

'रीसेट' को एक और साझा पॉइंटर लेने के लिए ओवरलोड किया गया है, इस स्थिति में यह असाइनमेंट के बराबर है। –

+0

कैशकॉ: क्या आप 'shared_ptr साझा (अन्य) लाइन 'की भूमिका की व्याख्या कर सकते हैं;' 'ऑपरेटर =' के कार्यान्वयन में? – freitass

2

foo.reset(p)shared_ptr(p).swap(foo) के बराबर होने का परिभाषित किया गया है।

असाइनमेंट तार्किक कॉपी और स्वैप के बराबर है, और संभवतः कि जिस तरह से लागू किया। तो foo = shared_ptr(p);foo.swap(shared_ptr(p)) के बराबर है। यदि संकलक में बहुत बुरा दिन हो तो संभवतः वहां एक अतिरिक्त प्रति के साथ।

तो उदाहरण आप दे में, मैं नहीं उन दोनों के बीच चयन करने के लिए बहुत है लगता है। अन्य मामले हो सकते हैं जहां यह महत्वपूर्ण है। लेकिन रीसेट, इसलिए जहाँ तक हो रही सही Deleter का सवाल है, तो आप को कवर कर रहे हैं p कि टेम्पलेट निर्माता करता है के स्थिर प्रकार का एक ही टेम्पलेट आधारित कब्जा करता है।

काम का मुख्य उपयोग होता है जब आप प्रतिलिपि बनाना चाहते हैं किसी पूर्व-मौजूदा shared_ptr, एक ही वस्तु का स्वामित्व साझा करने के लिए। बेशक यह अस्थायी से असाइन करते समय ठीक काम करता है, और यदि आप विभिन्न reset अधिभार को देखते हैं तो वे विभिन्न रचनाकारों को दर्पण करते हैं। तो मुझे संदेह है कि आप वही चीजों को किसी भी तरह से प्राप्त कर सकते हैं।नई अंतर्निहित करने के लिए संलग्न -

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

जबकि रीसेट कॉल नई साझा वस्तु का निर्माण नहीं करता, बल्कि एक नए स्वामित्व बढ़ाने से एक नया साझा वस्तु बनाने (नियंत्रण वस्तु के माध्यम से) 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); 
}