2013-02-14 21 views
9

का उपयोग कर मैं सी ++ 0 एक्स/11 में स्मार्ट पॉइंटर्स के साथ काम करना शुरू कर रहा हूं और मैंने एक असाधारण स्थिति में भाग लिया है। मैं share_ptr का उपयोग कर किसी ऑब्जेक्ट का उदाहरण डालना चाहता हूं।अप-कास्टिंग std :: shared_ptr std :: dynamic_pointer_cast

वर्ग कक्षा बेस से विरासत को बढ़ाता है, जहां बेस क्लास में इसे पॉलीमोर्फिक बनाने के लिए आभासी विनाशक होता है (अन्यथा गतिशील_पोइंटर_कास्ट गैर-पॉलिमॉर्फिक क्लास कास्टिंग के बारे में शिकायत करता है)।

इसलिए यदि:

std::shared_ptr<Base> obj = std::make_shared<Base>(); 

और फिर मुझे क्या करना:

obj = std::dynamic_pointer_cast<Extend>(obj); 
  1. यह सुरक्षित है?
  2. ऑब्जेक्ट के अन्य पॉइंटर्स के साथ क्या होता है? क्या केवल ओबीजे इसे विस्तार के रूप में पेश कर रहा है, जबकि अन्य साझा पॉइंटर्स अभी भी इसे बेस के रूप में मानेंगे?
  3. क्या यह एक ही उदाहरण को अपस्टास्ट करना सुरक्षित है या मुझे कुछ और करना चाहिए?

संपादित करें: उत्तर के लिए धन्यवाद। असली सवाल यह था कि मैं इस सवाल से पूछ रहा था कि एक्सएमएल दस्तावेज़ों को एक सैक्स पार्सर का उपयोग करना है, लेकिन मुझे ऊपर/नीचे कास्टिंग के साथ ले जाया गया। क्या मैं इन सबसे छुटकारा चाहता था:

std::shared_ptr<Extend> ex = std::dynamic_pointer_cast<Extend>(obj); 
obj = ex; 

लेकिन यह सब पर कोई मतलब नहीं है, बजाय मैं सिर्फ एक वस्तु कारखाने का उपयोग करेंगे।

+4

कक्षा बी {}; कक्षा डी: बी {} बी * से डी * में रूपांतरण ** डाउन ** कास्टिंग है, जबकि डी * से बी * में रूपांतरण ** ** ** कास्टिंग है। मुझे लगता है कि आपके पास दिशानिर्देश अन्य तरीकों से हैं। –

उत्तर

10

यह एक अप-कास्ट नहीं है, लेकिन एक डाउन-कास्ट (आप कम से कम व्युत्पन्न कक्षा में कास्टिंग कर रहे हैं)। हालांकि:

क्या यह सुरक्षित है?

हाँ, यह सुरक्षित है, लेकिन जब से तुम एक वस्तु जिसका रन-टाइम प्रकार के लिए सूचक खिन्न की कोशिश कर रहे नहीं Extend, आप बदले में एक अशक्त सूचक मिल जाएगा है।

ऑब्जेक्ट के अन्य पॉइंटर्स के साथ क्या होता है? क्या केवल ओबीजे इसे विस्तार के रूप में पेश कर रहा है, जबकि अन्य साझा पॉइंटर्स अभी भी इसे बेस के रूप में मानेंगे?

आपके यहां एक गलतफहमी है: ऑब्जेक्ट में पॉइंटर को घटाकर ऑब्जेक्ट को बदलना नहीं है। यदि ऑब्जेक्ट लक्ष्य प्रकार का नहीं है, तो आपको इसके लिए एक डाउनकास्ट पॉइंटर नहीं मिलेगा।पॉइंट ऑब्जेक्ट का प्रकार (कोई ऑब्जेक्ट) संकलन-समय पर निर्धारित होता है और नहीं बदलेगा।

क्या यह एक ही उदाहरण को अपनाने के लिए सुरक्षित है या मुझे कुछ और करना चाहिए?

सुनिश्चित नहीं हैं कि आप यहाँ क्या मतलब है, इस सवाल के निर्माण शायद ऊपर गलत धारणा से उपजी है। हालांकि, इस अनुदेश:

obj = std::dynamic_pointer_cast<Extend>(obj); 

obj एक अशक्त सूचक देगा। असाइनमेंट स्वयं कानूनी है, क्योंकि आप एक व्युत्पन्न कक्षा में एक (स्मार्ट) पॉइंटर को बेस क्लास में एक (स्मार्ट) सूचक को असाइन कर सकते हैं। हालांकि, असाइनमेंट के दाहिने तरफ एक शून्य सूचक (ऊपर लिखे गए कारणों के कारण) का मूल्यांकन करता है, इसलिए आपको अंततः obj को असाइन किया गया एक शून्य सूचक मिलेगा।

जब से तुम मूल रूप से बस, obj को रीसेट कर रहे हैं objmake_shared<>() के माध्यम से बनाया वस्तु को पिछले साझा सूचक, इस वस्तु के बाद से ऊपर काम किया जाता है नष्ट हो जाएगा है।

+0

हां बिल्कुल, और मुझे अभी एहसास हुआ कि मैं इसे गलत तरीके से जा रहा हूं। धन्यवाद। जो मैं करने की कोशिश कर रहा हूं वह आधार से विस्तार करने के लिए कक्षा के सदस्य को अप-कलाकार बना रहा है। –

+0

अंतिम प्रश्न निश्चित रूप से टाइप-कास्टिंग 'ओबीजे' के बारे में है और फिर परिणाम को उसी' obj' चर में वापस संग्रहीत करना है। –

+0

@ रोबकेनेडी: मैं देखता हूं, स्पष्टीकरण के लिए धन्यवाद। मैंने अपना जवाब संपादित किया। –

6

यदि अंतर्निहित वस्तु वास्तव में उस प्रकार का है तो आप केवल एक सुपर प्रकार पर डाले जा सकते हैं। कास्टिंग अचानक आपकी अंतर्निहित वस्तु को नई गुण नहीं दे सकता है।

std::make_shared<Base>(); 

विल, कवर के तहत फोन: new Base

इसका मतलब है आप नहीं कर सकते कि:

obj = std::dynamic_pointer_cast<Extend>(obj); 

किसी भी एक से अधिक आप एक new Base पर dynamic_cast इस्तेमाल कर सकते हैं यह कुछ है कि ऐसा नहीं है में बनाने के लिए। आपको make_shared<Extend> की आवश्यकता होगी और फिर shared_ptr<Base> का उपयोग करके इसे पास कर दें।

+0

हाँ मैंने कक्षा को विस्तारित करने के तरीके को कॉल करने का प्रयास करते समय यह पता लगाया। काफी हद तक संकलक ने लाइन के बारे में शिकायत नहीं की थी जहां मैं ऊपर कास्टिंग कर रहा था। तो एक std :: shared_ptr अप-कास्टिंग सवाल से बाहर है? –

+1

नहीं, यह सवाल से बाहर नहीं है, लेकिन अगर आप अंतर्निहित वस्तु वास्तव में उस प्रकार के हैं तो आप केवल एक सुपर प्रकार पर जा सकते हैं। कास्टिंग अचानक आपकी अंतर्निहित वस्तु को नई गुण नहीं दे सकता है। – Benj

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