2011-02-27 8 views
7

मान लें DerivedClass से BaseClass
चाहेंगे निम्नलिखित काम ली गई है?बढ़ावा :: shared_ptr और बताए व्युत्पन्न वर्ग

boost::shared_ptr<BaseClass> a(new BaseClass()); 
boost::shared_ptr<DerivedClass> b(new DerivedClass()); 
a=b; 

इस question के बाद, मैं समझता हूँ कि अब a अंक प्राप्त होता है और b अंक आधार पर (है ना?)

इसके अलावा, अब अगर मैं a के माध्यम से एक समारोह कॉल यह व्युत्पन्न कार्यान्वयन कहेंगे ?

उत्तर

13
... 
a=b; 

आप a को फिर नियत रहे हैं और इसलिए aऔरb होगा अब DerivedClass वस्तु को दोनों बिंदु। BaseClass ऑब्जेक्ट नष्ट हो जाएगा, क्योंकि इसकी संदर्भ संख्या इस बिंदु पर शून्य होगी (a के आधार पर एक अलग ऑब्जेक्ट को इंगित करने के लिए पुन: असाइन किया जा रहा है)।

a के बाद से अब एक DerivedClass वस्तु, आभासी समारोह कॉल (BaseClass में परिभाषित किया गया और DerivedClass में ओवरराइड) के माध्यम से aDerivedClass में इसी सदस्य कार्यों कहेंगे को इंगित करता है।

जब a और b दोनों दायरे से बाहर निकलते हैं, तो DerivedClass ऑब्जेक्ट नष्ट हो जाएगा।

आप a (जैसे, गैर आभासी DerivedClass में कार्य करता है) के माध्यम से व्युत्पन्न वर्ग के लिए विशिष्ट कार्यों का उपयोग करने की जरूरत है, तो आप उपयोग कर सकते हैं:

boost::dynamic_pointer_cast<DerivedClass>(a)->SomeFunctionOnlyInDerivedClass(); 
बेशक

यह सिर्फ एक संक्षिप्त उदाहरण है कि उपयोग दिखाता है । उत्पादन कोड में, आप निश्चित रूप से पॉइंटर को संदर्भित करने से पहले DerivedClass पर एक सफल कलाकार के लिए परीक्षण करेंगे।

+1

क्या 'static_pointer_cast' भी काम नहीं करेगा और इस प्रकार 'व्युत्पन्न क्लास' में गैर-वर्चुअल फ़ंक्शन को कॉल करने का पसंदीदा तरीका होगा? 'बढ़ावा देने :: static_pointer_cast (क) -> SomeFunctionOnlyInDerivedClass();' – j00hi

4

मान लें DerivedClassBaseClass से लिया गया है। क्या निम्नलिखित काम करेंगे?

हां।

boost::shared_ptr<BaseClass> pbase(new DerivedClass()); 

(दोनों ही मामलों में यह मानते हुए BaseClass एक आभासी नाशक है।) स्मार्ट सूचक जितना संभव हो उतना एक सादे सूचक की तरह व्यवहार करते हैं, और BaseClass* pbase = new DerivedClass(); रूप में एक ही व्यवहार प्रदान करने के लिए डिज़ाइन किया गया है के साथ कुछ भी गलत नहीं है बस के रूप में, साथ ही वह जीवन भर-प्रबंधन भलाई।

इस सवाल के बाद, मैं समझता हूँ कि प्राप्त होने वाले अब a अंक और आधार के लिए b अंक (ना?)

नहीं, एक और ख होगा DerivedClass उदाहरण के लिए दोनों बिंदु। स्वैप जो लिंक किया गया आलेख ऑपरेटर = के अंदर एक अस्थायी वस्तु पर होता है। जब वह अस्थायी वस्तु दायरे से बाहर हो जाती है, तो बेस क्लास उदाहरण हटा दिया जाएगा।

इसके अलावा, अगर मैं a के माध्यम से कोई फ़ंक्शन कॉल करता हूं तो क्या यह व्युत्पन्न कार्यान्वयन को कॉल करेगा?

हां।

T * operator->() const // never throws 
{ 
    BOOST_ASSERT(px != 0); 
    return px; 
} 

ताकि व्यवहार एक जैसा ही होता है: यदि आप ऑपरेटर> के कार्यान्वयन को देखें, तो सभी यह करता है सूचक जो मौलिक ऑपरेटर> पर कहा जा रहा है वापसी है सादा सूचक

3

एक = बी करते समय आप ऑब्जेक्ट बी को इंगित करने के लिए बताते हैं। तो आप जिन सभी विधियों को कॉल करते हैं, आप ऑब्जेक्ट बी पॉइंट्स के बेस क्लास भाग पर कॉल करते हैं।

तो यदि इसमें वर्चुअल विधि है जो DerviedClass में अधिलेखित है, तो अधिलेखित संस्करण को कॉल किया जाता है।