2012-03-19 12 views
7

मुझे उप-वर्ग को उचित स्मार्ट पॉइंटर प्राप्त करने की अनुमति देने के लिए एक समाधान खोजने की आवश्यकता है।सबक्लास और get_shared_from_this()

class Parent : public enable_shared_from_this { 
    ... 
} 

class Child : public Parent { 
    public Child(){ 
    boost::shared_ptr<Parent> pointer=shared_from_this(); // should work 
    boost::shared_ptr<Child> pointer=shared_from_this(); // won't work. 

    ... 
} 

मैं साझा_from_this() का उपयोग कर सही स्मार्ट सूचक कैसे प्राप्त करूं?

संदर्भ:

मैं सूचक/श्रोता सामान का एक सा लिख ​​रहा हूँ, और कुछ वर्गों स्वाभाविक रूप से रजिस्टर और सूचक से खुद को अपंजीकृत करने की आवश्यकता होगी। उदाहरण के लिए,

class Body : extends Listener<BodyMessage>{ // listen for BodyMessage messages 
    public: 
    Body() { 
     Notifier<BodyMessage>::register(this); // register with the appropriate notifier 
    } 

    virtual ~Body { 
     Notifier<BodyMessage>::unregister(this); // unregister 
    } 

    bool notify(BodyMessage m){ ... } 

    ... 
} 

आम तौर पर मैं सिर्फ इस सूचक का प्रयोग करेंगे, और सब कुछ ठीक हो जाएगा। मुझे टेम्पलेट्स का उपयोग करने के लिए नोटिफ़ायर मिला है, इसलिए मैं केवल उन लोगों को संदेश भेज सकता हूं जो उन्हें सुनना चाहते हैं।

हालांकि, मैं स्मार्ट पॉइंटर्स का उपयोग करना चाहता हूं। सूचक इस तरह दिखाई देता है:

template<typename t> 
class Notifier { 
    public: 
    static void register<boost::shared_ptr<Listener<t>>> boost::shared_ptr<Listener<t>> listener); 

    ... 
} 

तो मैं इस सूचक किसी भी अधिक का उपयोग नहीं कर सकते हैं।

class Body : public boost::enable_shared_from_this, public Listener<BodyMessage> { 
    public: 
    Notifier<BodyMessage>::register(get_shared_ptr()); 
    ... 
} 

और वह निकायों के लिए काम करता है लगता है: स्वाभाविक रूप से, मैं शरीर का विस्तार enable_shared_from_this बनाया है। यह काम नहीं करता है, हालांकि, उपवर्गों निकायों के (या कम से कम, यह प्रतीत नहीं होता है) के लिए:

class BodyChild : public Body { 
    public: 
    BodyChild(){ 
     Notifier<BodyMessage>::register(get_shared_ptr()); 
} 

संभावना क्योंकि मैं एक shared_pointer डाली नहीं कर सकता। तो, मैं एक समाधान है कि

  • मुझे श्रोताओं के लिए साझा संकेत का उपयोग करें (के बाद से इन श्रोताओं भी अन्य स्मार्ट सूचक संदर्भों में इस्तेमाल किया जाता है) की सुविधा देता है,
  • उपयोग करते हुए, मुझे सूचक और श्रोताओं टेम्पलेट की सुविधा देता है बना सकते हैं संदेश स्वयं टेम्पलेट के लिए टाइप करें, इसलिए विशिष्ट संदेशों को सुनना बहुत आसान है और इसलिए मुझे एक संदेश डीकोड करने की आवश्यकता नहीं है, और
  • सरल है?

मैं अन्य विचारों के लिए खुला हूं, लेकिन अगर मैं इसे काम पर ला सकता हूं, तो मैं रोमांचित हूं।

+0

अजीब बात है (कोएनिग देखने के लिए static_pointer_cast धन्यवाद अर्हता प्राप्त करने की कोई जरूरत), मैं के खिलाफ भाग गया:

के बाद से this सही गतिशील प्रकार की है, तो आप shared_from_this() की वापसी मूल्य पर boost::static_pointer_cast आह्वान कर सकते हैं आज यह मुद्दा है। पर्यवेक्षक पैटर्न के लिए स्मार्ट पॉइंटर्स का उपयोग करना एक बहुत अच्छा विचार साबित हुआ। आधे काम स्वचालित रूप से किए जाने के लिए आप 'बूस्ट :: सिग्नल' का भी उपयोग कर सकते हैं (विशेष रूप से 'scoped_connection' ऑब्जेक्ट्स के साथ)। –

+0

आपको अपने नोटिफायर/श्रोता प्रणाली के लिए 'std :: shared_ptr' क्यों चाहिए/चाहिए?क्या श्रोताओं को वास्तव में नोटिफ़ायर के स्वामित्व में होना चाहिए, ताकि सभी नोटिफ़ायर चले जाने के बाद उन्हें नष्ट कर दिया जाए? या वास्तव में अन्य वस्तुओं हैं, जो सुनने की वस्तुओं का मालिक हैं और तत्काल और निर्माण का ख्याल रख सकते हैं? इस तरह की एक प्रणाली का निर्माण करते समय, मुझे वास्तव में बहुत अधिक नियंत्रण रखने और इसे दूर करने में काफी मददगार नहीं मिला है। – LiKao

+0

@LiKao: पर्यवेक्षक पैटर्न लिखने का एक तरीका वास्तव में श्रोताओं को नोटिफ़ायर को जीवित रखना है, और विनाश पर अनसुलझा है (shared_ptr + boost :: सिग्नल <50 LOC) में लिखने के लिए उत्कृष्ट है। इसके विपरीत, मैंने पाया कि इस स्थिति में बहुत सरल और कठोर कुछ चिपकने से बेहतर कोड लिखने में मदद मिलती है (पढ़ें: अधिक रखरखाव योग्य)। –

उत्तर

6

आप कास्ट स्मार्ट पॉइंटर्स कास्ट कर सकते हैं, और बूस्ट आपको इसे कम करने के लिए कुछ टेम्पलेट प्रदान करता है। आपके पास उदाहरण है static_pointer_cast और dynamic_pointer_cast जो आपको पॉइंटर के माध्यम से "कास्ट" करने की अनुमति देता है।

boost::shared_ptr<Child> p = static_pointer_cast<Child>(shared_from_this()); 

+1

static_pointer_cast (...) शायद इस मामले में जाने का सबसे अच्छा तरीका है; धन्यवाद। बेशक, मुझे यह एहसास हो रहा है कि शायद मेरे पास नोटिफ़ायर द्वारा उपयोग किए जाने वाले स्मार्ट पॉइंटर्स दोनों नहीं हो सकते हैं और ऑब्जेक्ट्स खुद को निर्माण पर जोड़ते हैं, क्योंकि किसी ऑब्जेक्ट का स्मार्ट पॉइंटर कन्स्ट्रक्टर समाप्त होने तक "उपलब्ध नहीं" होता है। – whiterook6

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