2012-08-26 7 views
5

सबसे पहले, मुझे एहसास है कि यह पूरी तरह से shared_ptr के उद्देश्य से विरोधाभास करता है। मैं कुछ लाइब्रेरी कोड से निपट रहा हूं जहां कण सिस्टम के उदाहरणों को प्रत्येक कण के लिए उपयोग किए गए बनावट को सेट करने के लिए निर्माण के दौरान उन्हें साझा किया गया एक साझा_पीआरआर होने की उम्मीद है। बात यह है कि, मैंने पहले से ही अपने बाकी कार्यक्रम को ऐसे तरीके से बनाया है जहां मेरे बनावट के पास ठोस स्वामित्व है (यदि यह सही शब्द है) - TextureCache सभी बनावट का मालिक है। इसलिए मुझे इस कण सिस्टम सिस्टम के साथ काम करने की ज़रूरत है, बिना इसे मेरे बनावट को हटाने की इजाजत दी। अगर मैं बस ParticleSystem(std::shared_ptr<Texture>&myTexture) जैसे नए उदाहरण को बनाना चाहता था तो यह अपने विनाश पर बनावट को नष्ट करने का प्रयास करेगा (जो एक अवांछित और अमान्य ऑपरेशन है, क्योंकि मेरे बनावट new के साथ भी नहीं बनाए गए हैं)।किसी ऑब्जेक्ट को साझा करने के लिए साझा किए गए फ़ंक्शन पर ऑब्जेक्ट पास करें, वास्तव में स्वामित्व साझा किए बिना

  1. एक shared_ptr समारोह है कि ParticleSystem बनाता में बनावट पकड़े बनाएँ:

    स्पष्ट तरीका मैं इस समस्या को हल देख कुछ इस तरह है।

  2. फिर प्लेसमेंट का उपयोग करके, साझा_ptr को उसी स्मृति स्थान में पुनर्निर्मित करें जैसा मैंने अभी साझा किया है। बनावट में अब संदर्भ संख्या 2.
  3. कण प्रणाली बनाएं।
  4. साझा_प्टर को दायरे से बाहर जाने दें। इसके deconstructor को कॉल किया जाएगा क्योंकि इसे ढेर पर आवंटित किया गया था, और यह केवल 1 तक संदर्भ गणना को कम करेगा। इस प्रकार वस्तु के लिए संदर्भ गणना हमेशा वास्तव में 1 से अधिक होगी, और इसलिए यह स्वचालित रूप से कभी नष्ट नहीं हो जाएगी।

मेरा मानना ​​है कि यह समाधान ध्वनि है, लेकिन यह अभी भी अविश्वसनीय रूप से हैकिश लगता है। क्या मेरी समस्या को हल करने का कोई बेहतर तरीका है?

+0

नहीं क्यों अपने बनावट कैश में shared_ptrs है? –

+0

@ वॉन जो व्यवहार्य है, लेकिन यह बनावट के बजाए बनावट के लिए पॉइंटर्स को ट्रैक करके संकेतों का एक अनावश्यक अतिरिक्त स्तर जैसा प्रतीत होता है और यह साझा पॉइंटर्स का अर्थपूर्ण रूप से दुरुपयोग होगा क्योंकि बनावट कैश अभी भी ठीक होने पर निर्णय लेने के लिए ज़िम्मेदार है बनावट को जारी करने के लिए - यह * साझाकरण * स्वामित्व नहीं होगा। Deleter के रचनात्मक दुरुपयोग के लिए – Ponkadoodle

उत्तर

4

आप (कि आप अपने आप से प्रबंधन) स्मार्ट सूचक जैसे shared_ptr उम्मीद कोड करने के लिए अप्रबंधित सूचक पास करना चाहते हैं के साथ एक shared_ptr बना सकते हैं, आप कर सकते हैं बस खाली बनाकर को निष्क्रिय «स्मार्ट» सूचक कार्यक्षमता, लेकिन aliasing निर्माता के माध्यम से नहीं-अशक्त shared_ptr:

Texture* unmanagedPointer = ... 
shared_ptr<Texture> smartPointer(shared_ptr<Texture>(), unmanagedPointer); 

यह समाधान, अधिक कुशल और कम से कस्टम Deleter अन्य सुझाव दिया है के बाद से कोई नियंत्रण ब्लॉक आवंटन और संदर्भ गिनती जा रहा है पर।

कुछ अतिरिक्त जानकारी यहां पाया जा सकता है:

What is the difference between an empty and a null std::shared_ptr in C++?

How to avoid big memory allocation with std::make_shared

0

स्टोर shared_ptr स्टोर में कैश वॉन कैटो के सुझाव देते हैं। जब कोई भी उपयोग करता कैश से एक बनावट को निकालने के लिए यह सिर्फ जाँच लें कि shared_ptr रिटर्न 1 की use_count समारोह है, जो कैश का मतलब केवल मालिक

3

आप custom deleter that does nothing साथ shared_ptr बना सकते हैं। यह इस shared_ptr के स्वामित्व वाले बनावट को हटाने से रोक देगा।

struct null_deleter 
{ 
    void operator()(void const *) const 
    { 
    } 
}; 

shared_ptr<Texture> CreateTexture(Texture* myTexture) 
{ 
    shared_ptr<Texture> pTexture(myTexture, null_deleter()); 
    return pTexture; 
} 
+0

+1। –

1

shared_ptr आप एक कस्टम Deleter आपूर्ति करने के लिए अनुमति देता है। तो shared_ptr का उपयोग मॉलोक या जो भी मेमोरी आवंटन योजना आप कर रहे हैं, के साथ आवंटित स्मृति के लिए किया जा सकता है, आप इसे म्यूटेक्स को स्वचालित रूप से अनलॉक करने या फ़ाइल बंद करने के लिए भी उपयोग कर सकते हैं, लेकिन मैं digress। आप एक अशक्त Deleter जो कुछ भी नहीं होता है जब उसके referene गिनती तक पहुँच जाता है 0.