2010-10-13 14 views
5

मैं सी ++ का उपयोग कर रहा हूं। दृश्य स्टूडियो 2010 का उपयोग कर सी ++ 0x सही होने के लिए।गैर-घुसपैठ स्मार्ट पॉइंटर्स विरासत और एकाधिक विरासत के संबंध में कैसे व्यवहार करते हैं?

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

अब इस वर्ग जेड एक वर्ग एक्स अपने आवेदन के कुछ हिस्सों दसवीं कक्षा की ओर इशारा के साथ काम करेंगे से विरासत, दूसरों वर्ग जेड

  • की ओर इशारा के साथ काम मैं अभी भी स्मार्ट संकेत का उपयोग कर सकते हो जाएगा?
  • क्या साझा पॉइंटर्स अभी भी काम करते हैं यदि मेरे पास कुछ ऐसा है जो एक्स और अन्य को संदर्भित करता है जो Z को संदर्भित करता है? क्या यह गारंटी है कि उदाहरण के लिए अंतिम साझा सूचक का विनाश (भले ही यह std::shared_ptr<X> या std::shared_ptr<Z> है) उदाहरण को हटा देता है? क्या मुझे यकीन है कि अगर मैं std::shared_ptr<X> हटा देता हूं, तो उदाहरण तब तक रखा जाता है जब तक कोई अन्य std::shared_ptr<Y> है?

अब मान लें कि मैं एकाधिक वंशानुक्रम का उपयोग करें, जहां जेड std::shared_ptr<Z> साथ std::shared_ptr<Y> साथ कक्षाएं एक्स और वाई अपने आवेदन के कुछ हिस्सों std::shared_ptr<X> के साथ काम करेंगे, दूसरों को और दूसरों से इनहेरिट करती है।

  • क्या मैं अभी भी साझा पॉइंटर्स का उपयोग इस तरह से कर सकता हूं?
  • क्या यह अभी भी गारंटी है कि केवल अंतिम स्मार्ट सूचक (चाहे वह एक्स, वाई या जेड को इंगित करता है) उदाहरण को हटा देता है?

वैसे, मैं सुरक्षित रूप से एक स्मार्ट पॉइंटर को दूसरे पर कैसे डाल सकता हूं, उदा। कास्ट std::shared_ptr<Z> से std::shared_ptr<X>? क्या यह काम करता है? क्या यह अनुमति है?

ध्यान दें कि मैं स्पष्ट रूप से गैर-घुसपैठ पॉइंटर्स (नए std::shared_ptr और std::weak_ptr सी ++ 0x में) के रूप में स्पष्ट रूप से संदर्भित करता हूं। घुसपैठ करने वाले पॉइंटर्स (जैसे बूस्ट में) का उपयोग करते समय, यह शायद काम करता है क्योंकि उदाहरण काउंटर रखने के लिए जिम्मेदार है।

उत्तर

6

हां यह मानक, §20.9.11.2.10 [util.smartptr.shared.cast] द्वारा समर्थित है।

utils आप की जरूरत है:

  • std::static_pointer_cast<>()
  • std::dynamic_pointer_cast<>()

वे अपने सी ++ 03 सहकर्मियों के static_cast<>() और dynamic_cast<>() रूप में एक ही अर्थ विज्ञान है। एक अंतर यह है कि वे केवल std::shared_ptr एस पर काम करते हैं। और केवल वर्बोज़ करने के लिए, वे वही करते हैं जो आप उम्मीद करते हैं और मूल और नए कलाकार shared_ptr एस के बीच संदर्भ गणना को सही ढंग से साझा करते हैं।

struct X { virtual ~X(){} }; 
struct Y : public X {}; 
struct Z : public X {}; 

int main() 
{ 
    { 
     //C++03 
     X* x = new Z; 
     Z* z = dynamic_cast<Z*>(x); 
     assert(z); 
     x = new Y; 
     z = dynamic_cast<Z*>(x); 
     assert(!z); 
     z = static_cast<Z*>(x); 
     assert(z); //EVIL!!! 
    } 

    { 
     //C++0x 
     std::shared_ptr<X> x{new Z}; 
     std::shared_ptr<Z> z{std::dynamic_pointer_cast<Z>(x)}; 
     assert(z); 
     x = std::make_shared<Y>(); 
     z = std::dynamic_pointer_cast<Z>(x); 
     assert(!z); 
     z = std::static_pointer_cast<Z>(x); 
     assert(z); //EVIL!!! 

     // reference counts work as expected. 
     std::shared_ptr<Y> y{std::static_pointer_cast<Y>(x)}; 
     assert(y); 

     std::weak_ptr<Y> w{y}; 
     assert(w.expired()); 

     y.reset(); 
     assert(w.expired()); 

     x.reset(); 
     assert(!w.expired());  
    } 
    { 
     //s'more nice shared_ptr features 
     auto z = std::make_shared<X>(); 
     std::shared_ptr<X> x{z}; 
     assert(z == x); 
     x = z; //assignment also works. 
    } 
} 
+0

वाह कभी नहीं इस के बारे में सुना ... O__o किसी भी संसाधन में यह करने के लिए कोई संदर्भ मैं C++ 0x अन्य (indigest) मसौदा से ... – Klaim

+0

मुझे यकीन है कि डाले के लिए नहीं पता था पर मिल सकता है जहां तक ​​मैंने इसे देखा। हालांकि मुझे दृढ़ता से संदेह था कि वे वहां थे क्योंकि वे मूल Boost.Smartptr लाइब्रेरी का हिस्सा थे। –

+0

अंतर्निहित कास्ट ऑपरेटरों के सामने कृपया "std ::" से छुटकारा पाएं।इसके अलावा, इस प्रकार के गतिशील कलाकारों को पॉलिमॉर्फिक कक्षाओं की आवश्यकता होती है। आपके उदाहरण वर्ग polymorphic नहीं हैं। – sellibitze