2012-02-14 9 views
5

अलेक्जेंड्रेस्कू और विकिपिपिडिया पढ़ना मुझे पॉइंट और संदर्भ काउंटर ढेर पर संग्रहीत किया जाता है। फिर उल्लेख किया गया है कि संदर्भ गिनती अक्षम है क्योंकि ढेर पर काउंटर आवंटित किया जाना चाहिए? यह ढेर पर क्यों नहीं संग्रहीत है?सी ++ स्मार्ट पॉइंटर कार्यान्वयन क्यों पॉइंट के साथ ढेर पर संदर्भ काउंटर रखते हैं?

+0

क्या आप जो वर्णन कर रहे हैं उसका एक उदाहरण दिखा सकते हैं? –

+0

आप और कैसे करेंगे? –

+0

दोनों "संदर्भ काउंटर" और "ढेर" केवल कार्यान्वयन विवरण हैं।वास्तविक गोमांस यह है कि साझा स्वामित्व अर्थशास्त्र केवल गतिशील आवंटन के साथ लागू किया जा सकता है। –

उत्तर

9

क्योंकि जैसे ही आप स्मार्ट पॉइंटर का वर्तमान उदाहरण गुंजाइश से बाहर हो जाते हैं, आप इसे खो देंगे।

स्वचालित स्टोरेज ऑब्जेक्ट्स को अनुकरण करने के लिए एक स्मार्ट पॉइंटर का उपयोग गतिशील रूप से आवंटित किया गया था। स्मार्ट पॉइंटर्स स्वयं स्वचालित रूप से प्रबंधित होते हैं। तो जब कोई नष्ट हो जाता है, तो स्वचालित भंडारण में जो भी स्टोर होता है वह भी नष्ट हो जाता है। लेकिन आप संदर्भ काउंटर खोना नहीं चाहते हैं। तो आप इसे गतिशील भंडारण में स्टोर करते हैं।

3

इसे स्टैक पर संग्रहीत नहीं किया जा सकता है क्योंकि तब ऑब्जेक्ट की प्रतिलिपि के परिणामस्वरूप रिफॉउंट की प्रतिलिपि भी होगी, जो इसके उद्देश्य को हरा देगा।

1

के रूप में अन्य लोगों ने बताया है, ढेर एक उपयुक्त स्थान संदर्भ गिनती रखने के लिए क्योंकि वस्तु वर्तमान ढेर फ्रेम से अधिक जीवित नहीं हो सकता है (इस स्थिति में संदर्भ गिनती दूर जाना होगा!)

यह लायक है यह ध्यान में रखते हुए कि ढेर पर संदर्भ गणना डालने से जुड़ी कुछ अक्षमताओं को वस्तु के साथ "एक साथ" संग्रहित करके दूर किया जा सकता है। बढ़ावा में, यह boost::make_shared (shared_ptr के लिए) या boost::intrusive_ptr का उपयोग करके पूरा किया जा सकता है।

1

विभिन्न उद्देश्यों के लिए डिज़ाइन किए गए विभिन्न प्रकार के स्मार्ट पॉइंटर्स हैं। जिस सूचक के बारे में आप बात कर रहे हैं वह साझा स्मार्ट पॉइंटर (std::shared_ptr) है, जो एकाधिक स्थानों से ऑब्जेक्ट स्वामित्व साझा करने में सहायता करता है। shared_ptr की सभी प्रतियां उसी काउंटर वैरिएबल को बढ़ाती हैं और घटाती हैं, जो ढेर पर रखी जाती है, क्योंकि पहली प्रतिलिपि के बाद भी shared_ptr की सभी प्रतियों के लिए यह उपलब्ध होना आवश्यक है।

तो, shared_ptr आंतरिक रूप से दो पॉइंटर्स रखता है: ऑब्जेक्ट और काउंटर पर। स्यूडोकोड:

class SharedPointer<T> { 
public: 
// ... 
private: 
    T* obj; 
    int* counter; 
} 

वैसे, जब आप std::make_shared साथ वस्तु बनाने, कार्यान्वयन के लिए पर्याप्त स्मृति आवंटन दोनों काउंटर और वस्तु धारण करने के लिए और फिर उन्हें साथ-पक्ष का निर्माण करके आवंटन का अनुकूलन कर सकते हैं।

यह चरम पर यह चाल हमें एक घुसपैठ संदर्भ गणना पैटर्न प्रदान करती है: ऑब्जेक्ट आंतरिक रूप से अपना काउंटर रखता है और AddRef और Release कार्यों को बढ़ाने और घटाने के लिए प्रदान करता है। आप घुसपैठ स्मार्ट पॉइंटर का उपयोग कर सकते हैं, उदा। boost::intrusive_ptr, जो इस मशीनरी का उपयोग करता है और इस प्रकार एक और अलग काउंटर आवंटित करने की आवश्यकता नहीं है। यह आवंटन के मामले में तेज़ है, लेकिन नियंत्रित वर्ग परिभाषा के काउंटर को इंजेक्ट करने की आवश्यकता है। std::unique_ptr या boost::scoped_ptr:

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

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