2010-12-30 4 views
12

जब पढ़ने "के अलावा सी ++ स्टैंडर्ड लाइब्रेरी: एक परिचय बूस्ट करने के लिए", मैं एक बहुत ही दिलचस्प उदाहरण है:कितना बढ़ावा :: ~ shared_ptr काम करता है?

class A 
{ 
public: 
    virtual void sing()=0; 
protected: 
    virtual ~A() {}; 
}; 

class B : public A 
{ 
public: 
    virtual void sing() 
    { 
     std::cout << "Do re mi fa so la"<<std::endl;; 
    } 
}; 

और मैं कुछ परीक्षण करना:

int main() 
{ 

//1 
std::auto_ptr<A> a(new B); //will not compile ,error: ‘virtual A::~A()’ is protected 

//2 
A *pa = new B; 
delete pa; //will not compile ,error: ‘virtual A::~A()’ is protected 
delete (dynamic_cast<B*>(pa)); //ok 

//3 
boost::shared_ptr<A> a(new B);//ok 

} 

क्या मैं यहाँ बहुत उत्सुक हूँ कैसे ~ shared_ptr काम करता है? यह व्युत्पन्न कक्षा बी कैसे कम करता है?

आपकी मदद के लिए धन्यवाद अग्रिम!

  1. टेम्पलेट निर्माण समारोह
  2. संसाधन ~ shared_ptr में नष्ट नहीं किया है, यह:

    धन्यवाद सब, मैं कैसे ~ shared_ptr काम करता है

    class sp_counted_base 
    { 
    public: 
        virtual ~sp_counted_base(){} 
    }; 
    
    template<typename T> 
    class sp_counted_base_impl : public sp_counted_base 
    { 
    public: 
        sp_counted_base_impl(T *t):t_(t){} 
        ~sp_counted_base_impl(){delete t_;} 
    private: 
        T *t_; 
    }; 
    
    
    class shared_count 
    { 
    public: 
        static int count_; 
        template<typename T> 
        shared_count(T *t): 
         t_(new sp_counted_base_impl<T>(t)) 
        { 
         count_ ++; 
        } 
        void release() 
        { 
         --count_; 
         if(0 == count_) delete t_; 
        } 
        ~shared_count() 
        { 
         release(); 
        } 
    private: 
        sp_counted_base *t_; 
    }; 
    int shared_count::count_(0); 
    
    template<typename T> 
    class myautoptr 
    { 
    public: 
        template<typename Y> 
        myautoptr(Y* y):sc_(y),t_(y){} 
        ~myautoptr(){ sc_.release();} 
    private: 
        shared_count sc_; 
        T *t_; 
    }; 
    
    int main() 
    { 
        myautoptr<A> a(new B); 
    } 
    

    कुंजी है के बारे में एक सरल नमूना बारे में shared_count

उत्तर

10

द्वारा हटा दिया गया है आश्चर्य की बात है, यहां कुंजी boost::shared_ptr विनाशक नहीं है लेकिन इसके निर्माता (ओं) हैं।

आप boost/shared_ptr.hpp पर गौर करते हैं, तो आपको लगता है कि shared_ptr<T> 'बस' नहीं है एक निर्माता की उम्मीद कर एक T * लेकिन है देखेंगे:

template<class Y> 
explicit shared_ptr(Y * p); 

//3 में जब आप एक boost::shared_ptr एक B * से निर्माण, A * करने के लिए कोई रूपांतरण होता है, और shared_ptr आंतरिक वास्तविक B प्रकार के साथ बनाया गया है। ऑब्जेक्ट के विनाश पर, B पॉइंटर (बेस क्लास पॉइंटर के माध्यम से नहीं) पर विलोपन होता है।

+1

तकनीकी रूप से बोलते हुए, यह बी * से ए * में रूपांतरण करता है। सूचक के बाद की सभी पहुंच प्रकार ए * का उपयोग करेंगे। टाइप बी पर ऑपरेशंस मानक बहुरूपता के माध्यम से होते हैं (वे ए * के माध्यम से जाते हैं)। एकमात्र अपवाद विनाशक है, जिसे shared_ptr अपने "हटाना" तंत्र (या इसके कुछ सामान्यीकरण) के माध्यम से याद करता है। – nobar

3

shared_ptr कक्षा टेम्पलेट में वर्ग प्रकार shared_count का सदस्य है, जो बदले में sp_counted_base वर्ग के प्रकार सूचक का सदस्य है। कक्षा shared_count के लिए कन्स्ट्रक्टर टेम्पलेट इस सदस्य को क्लास टेम्पलेट sp_counted_impl_p के उदाहरण के लिए पॉइंटर असाइन करता है जो कि shared_ptr::value_type द्वारा नहीं, कन्स्ट्रक्टर तर्क के प्रकार से टेम्पलेट किया गया है। sp_counted_base में शुद्ध वर्चुअल सदस्य फ़ंक्शन dispose है जो sp_counted_impl_p द्वारा ओवरराइट किया गया है। क्योंकि sp_counted_impl_p आपके उदाहरण में B टाइप करता है, यह बेस क्लास विनाशक के बिना इसे हटा सकता है, और क्योंकि यह वर्चुअल प्रेषण का उपयोग करता है, प्रकार रनटाइम पर निर्धारित होता है। इस विधि को पैरामीट्रिक और उप प्रकार के पॉलीमोर्फिज्म के संयोजन की आवश्यकता होती है।