2015-12-11 16 views
15

अगर दो पुस्तकालयों (dynamicaly जुड़े) नई और का अपना विश्व स्तर पर अधिरोहित संस्करण है तो क्या होता है ऑपरेटरों हटा सकते हैं और वे अपने स्वयं के स्मृति प्रबंधन का उपयोग करें?नए और ऑपरेटरों को नष्ट पुस्तकालयों में ओवरराइड

यह आम तौर पर एक पुस्तकालय के अंदर स्मृति प्रबंधन सुविधाओं जहाज के लिए गलत है, या कुछ मामलों में अच्छा हो सकता है केवल कुछ विशिष्ट वर्गों के लिए स्मृति प्रबंधन प्रदान करने के लिए कर सकते हैं, को परिभाषित केवल वर्ग-विशेष नई और हटाना ऑपरेटरों को ओवरराइड?

क्या स्थिर लिंक्ड पुस्तकालयों के मामले में कुछ अंतर हैं?

+0

आपके पास एक विशिष्ट उपयोग-मामला है? 'नया' और 'हटाएं' ओवरराइड किया जा सकता है, लेकिन इसके लिए क्या? या यह एक सैद्धांतिक प्रश्न है (जो कि बहुत उन्नत उपयोगकर्ताओं के लिए होगा और मुझे लगता है कि उपयोग करता है)? – Elyasin

+4

गतिशील रूप से जुड़े पुस्तकालय मौजूद नहीं हैं, जहां तक ​​मानक सी ++ का संबंध है, इसलिए आपका प्रश्न प्लेटफ़ॉर्म-विशिष्ट है। क्या आप एक विशिष्ट मंच में रूचि रखते हैं? –

+0

@ सेबेस्टियन रेडल यूनिक्स से संबंधित, .so – nyarlathotep108

उत्तर

8

सामान्यतः, इसे "यहां ड्रैगन" लेबल किया गया है। यह सभी प्रकार की चीजों पर निर्भर करता है। अक्सर दो पुस्तकालय लड़ेंगे, और नया और हटाना उनमें से एक द्वारा ओवरराइड हो जाएगा - यह सबसे अच्छा है जिसके लिए आप उम्मीद कर सकते हैं।

विकल्प:

  • लाइब्रेरी एक शुरू होता है। ओवरराइड नया/ हटाएं, कुछ मेमोरी आवंटित करता है। लाइब्रेरी बी शुरू होता है और ओवरराइड करता है। सिस्टम शट डाउन पर, लाइब्रेरी ए की मेमोरी लाइब्रेरी बी के डिलीट से मुक्त होती है। वह ठीक नहीं है।

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

8

मैं मार्टिन सुंदर लगता है आपके प्रश्न का अच्छी तरह उत्तर देते हैं, यह बताते हुए कि क्या होता है और यह भी कुछ भी नहीं कि यह थोड़ा खतरनाक है और अत्यधिक सलाह नहीं है (वास्तव में ड्रैगन हो)। मुझे वैकल्पिक विकल्प प्रदान करके थोड़ा सा विस्तार करने दें: नए/हटाए जाने से बचने के लिए, और इसके बजाय आवंटक अवधारणा का उपयोग करें।

उदाहरण के लिए, यदि आप std :: vector को देखते हैं, तो आप देखते हैं कि यह किस प्रकार के स्टोर पर है, लेकिन आवंटक पर भी यह टेम्पलेट किया गया है। एक अनुरूप आवंटक लिखकर, आप वास्तव में नियंत्रित कर सकते हैं कि std :: vector आवंटित करता है और स्मृति को डी-आवंटित करता है। ध्यान दें कि यह कितना अच्छा और ढीला है यह है: स्मृति आवंटन पर पूर्ण नियंत्रण डालने में आपको कोई कठिनाई नहीं है, भले ही आप किसी भी मूल std :: वेक्टर स्रोत कोड को नहीं बदल सकते हैं।

आप पुस्तकालय बी एक विशिष्ट तरीके से आवंटन करना चाहते हैं, मैं क्या होता है:

  1. एक संभाजक कि जिस तरह से है कि std :: संभाजक करता संभाजक अवधारणा के अनुरूप लिखें।
  2. सुनिश्चित करें कि गतिशील स्मृति आवंटन का उपयोग करने वाले सभी वर्ग सीधे (जैसे उनके सदस्यों में से किसी एक के माध्यम से नहीं) आवंटक को जागरूक हैं।
  3. उन सभी वर्गों में टाइपपीफ टाइप करें ताकि वे डिफ़ॉल्ट रूप से आपके आवंटक का उपयोग कर सकें।

चरण 3 स्पष्ट करने के लिए, क्या मेरा मतलब है अपने पुस्तकालय का एक मूलभूत हेडर फाइल में कुछ इस तरह लिखना है:

template <class T> 
using my_lib::vector = std::vector<T, my_lib::MyAllocator<T>>; 

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

चरण 1 बहुत आसान (स्टेटलेस आवंटकों के लिए) से काफी मुश्किल हो सकता है (राज्य के आवंटकों के साथ कई गॉचा हैं)। चरण 2 के लिए, यह काफी सरल है जहां तक ​​कंटेनर के लिए गतिशील स्मृति जाता है क्योंकि मानक लाइब्रेरी में सभी कंटेनर पहले से ही इसका समर्थन करते हैं। लेकिन यदि आप उदाहरण के लिए गतिशील स्मृति का उपयोग कर रहे हैं बहुरूपता, आपको एक आवंटक-जागरूक तरीके से ऐसा करने के लिए थोड़ा अतिरिक्त काम करना होगा (शायद एक उपयुक्त रैपर लिखें)।

अगर किसी के पास कारणों के अच्छे उदाहरण हैं कि आप आवंटकों का उपयोग करने के विरोध में नया/हटाना क्यों चाहते हैं (उदा। क्योंकि ऐसा कुछ है जो आप आवंटकों के साथ नहीं कर सकते हैं) तो मुझे उन्हें सुनना होगा।

संपादित करें: और सिर्फ इस पूर्ण सर्कल को लाने के लिए, ध्यान दें कि लाइब्रेरी ए और बी का उपयोग करके कोई समस्या नहीं होगी यदि आप ऐसा करते हैं, क्योंकि कोई वैश्विक ऑपरेटरों को ओवरराइड नहीं किया गया है।

+1

मैंने सोचा था कि "यहां ड्रैगन" का अर्थ "ऐसा नहीं करना" के लिए पर्याप्त स्पष्ट था, लेकिन एक अच्छा विकल्प सुझाए जाने के लिए +1। –

+0

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

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