2010-12-13 10 views
10

मैं आने वाले नए सी ++ मानक में स्मार्ट पॉइंटर्स के साथ बस जा रहा हूं। हालांकि मैं shared_from_this फ़ंक्शन के उपयोग को समझने में विफल रहता हूं। यहाँ मैं क्या है:enable_shared_from_this (C++ 0x): मैं गलत क्या कर रहा हूं?

#include <iostream> 
#include <memory> 

class CVerboseBornAndDie2 : public std::enable_shared_from_this<CVerboseBornAndDie2> 
{ 
public: 
    std::string m_Name; 
    CVerboseBornAndDie2(std::string name) : m_Name(name) 
    { 
     std::cout << m_Name << " (" << this << ") is born!" << std::endl; 
    } 
    virtual ~CVerboseBornAndDie2() 
    { 
     std::cout << m_Name << " (" << this << ") is dying!" << std::endl; 
    } 
}; 

int main(){ 
    CVerboseBornAndDie2* vbad = new CVerboseBornAndDie2("foo"); 
    std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this(); 
} 

और यह लाइन

std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this(); 

में एक std :: bad_weak_ptr अपवाद फेंकता है तो मैं बजाय

std::shared_ptr<CVerboseBornAndDie2> p(vbad); 

यह काम करता है क्या करना है और मैं बाद में क्या कर सकते हैं

std::shared_ptr<CVerboseBornAndDie2> p2 = p.get()->shared_from_this(); 

इसलिए ऑब्जेक्ट होना चाहिए साझा_from_this का उपयोग करने से पहले एक साझा_ptr से संबंधित है? लेकिन मैं इसे पहले से कैसे जान सकता हूं?

उत्तर

22

यह shared_from_this का उपयोग करने की एक पूर्व शर्त है कि कम से कम एक shared_ptr मौजूद होना चाहिए जो वस्तु में प्रश्न का मालिक है। इसका अर्थ यह है कि आप का उपयोग केवल shared_ptr को पुनर्प्राप्त करने के लिए कर सकते हैं, जिस पर आपके पास कोई संदर्भ या सूचक है, आप इसका उपयोग यह पता लगाने के लिए नहीं कर सकते कि ऐसी ऑब्जेक्ट shared_ptr के स्वामित्व में है या नहीं।

आपको अपने डिज़ाइन को फिर से काम करने की आवश्यकता है ताकि आप की गारंटी हो कि ऐसी कोई ऑब्जेक्ट shared_ptr द्वारा प्रबंधित की जा रही है या आपको कभी भी जानने की आवश्यकता नहीं है या अंत में (और कम से कम वांछनीय) आप प्रबंधन के किसी अन्य तरीके को बनाते हैं यह ज्ञान

+0

अगर आप यह जानना चाहते हैं कि ऑब्जेक्ट किसी share_ptr द्वारा आयोजित किया गया है तो क्या आप साझा करना चाहते हैं तो साझा_from_this को कॉल के आसपास एक कोशिश-ब्लॉक डालें? मुझे नहीं पता कि यह (आगामी) मानक में कैसे निर्दिष्ट है, लेकिन यह अपरिभाषित व्यवहार प्रतीत नहीं होता है - यह अपवाद फेंक रहा है। – nobar

+1

@ नोबार: यह असामान्य रूप से असुरक्षित होगा। आप अनियंत्रित कार्यान्वयन विस्तार पर भरोसा करेंगे। 'shared_from_this' यह जांचने का एक तरीका नहीं है कि कोई ऑब्जेक्ट किसी साझा सूचक द्वारा स्वामित्व में है या नहीं; यह उस ऑब्जेक्ट से साझा पॉइंटर को पुनर्प्राप्त करने का एक तरीका है जिसे आप साझा पॉइंटर द्वारा स्वामित्व में रखते हैं। –

+0

मुझे लगता है कि आप सही हैं। सी ++ 0 एक्स मसौदा कहता है "कम से कम एक साझा_पीटीआर उदाहरण पी होगा जो स्वयं का है और टी।", लेकिन यह नहीं कहता कि अन्यथा क्या होता है। यह weak_ptr के संदर्भ में एक कार्यान्वयन दिखाता है (जो दर्शाता है कि एक अपवाद त्रुटि पर फेंक दिया जाएगा), लेकिन यह केवल एक "सुझाव" है। मुझे आश्चर्य है कि त्रुटि-अंततः अंततः बेहतर निर्दिष्ट किया जाएगा। – nobar

15

चार्ल्स उत्तर का विस्तार करने के लिए, जब आप enable_shared_from_this का उपयोग करते हैं तो आप आमतौर पर एक साझा_प्टर मौजूद होने की गारंटी के लिए नीचे कुछ ऐसा चाहते हैं।

class my_class : public std::enable_shared_from_this<my_class> 
{ 
public: 
    static std::shared_ptr<my_class> create() // can only be created as shared_ptr 
    { 
     return std::shared_ptr<my_class>(new my_class()); 
    } 
private 
    my_class(){} // don't allow non shared_ptr instances. 
}; 
+1

'बनाएं()' 'स्थिर 'होना चाहिए, है ना? –

+0

@ abyss.7: दरअसल। – ronag

+1

और डिफ़ॉल्ट रूप से साझा करने के लिए, आप कुछ के साथ कुछ उपयोग कर सकते हैं: 'try {return shared_from_this() वापसी करें; } पकड़ो (const bad_weak_ptr &) {वापसी make_shared (); } ' –

संबंधित मुद्दे