यह वह जगह है एक पुराने, उत्तर दिया, सवाल है, लेकिन @ एलेक्सेंड्रे ने पूछा, "कोई ऐसा क्यों करना चाहेगा?", और मैंने सोचा कि मैं एक उदाहरण उपयोग प्रदान कर सकता हूं जिसे मैं आज दोपहर पर विचार कर रहा हूं।
विरासत कोड। अंत में एक हटा ओबीजे के साथ नग्न पॉइंटर्स Obj * obj का उपयोग करता है।
दुर्भाग्य से मुझे ऑब्जेक्ट को ज़िंदा रखने के लिए कभी-कभी, कभी-कभी आवश्यकता नहीं होती है।
मैं इसे एक संदर्भित स्मार्ट पॉइंटर बनाने पर विचार कर रहा हूं। लेकिन अगर ref_cnt_ptr<Obj>
हर जगह उपयोग करना था, तो बहुत सारे कोड बदलने के लिए होगा। और यदि आप नग्न Obj * और ref_cnt_ptr को मिलाते हैं, तो आप ऑब्जेक्ट को पूरी तरह से हटा सकते हैं जब अंतिम ref_cnt_ptr चला जाता है, भले ही Obj * अभी भी जीवित है।
तो मैं एक clear_delete_ref_cnt_ptr बनाने के बारे में सोच रहा हूं। अर्थात। एक संदर्भ गिनती सूचक जहां डिलीट केवल एक स्पष्ट हटाने दिनचर्या में किया जाता है। इसे उसी स्थान पर उपयोग करना जहां मौजूदा कोड वस्तु के जीवनकाल को जानता है, साथ ही साथ मेरे नए कोड में जो ऑब्जेक्ट को ज़िंदा रहता है।
संदर्भ गणना को बढ़ाने और घटाने के रूप में clear_delete_ref_cnt_ptr को छेड़छाड़ की जाती है।
लेकिन स्पष्ट नहीं है जब संदर्भ गणना को clear_delete_ref_cnt_ptr विनाशक में शून्य माना जाता है।
केवल तभी खाली होना जब संदर्भ गणना को स्पष्ट हटाए जाने वाले ऑपरेशन में शून्य माना जाता है। जैसे कुछ में:
template<typename T> class explicit_delete_ref_cnt_ptr {
private:
T* ptr;
int rc;
...
public:
void delete_if_rc0() {
if(this->ptr) {
this->rc--;
if(this->rc == 0) {
delete this->ptr;
}
this->ptr = 0;
}
}
};
ठीक है, ऐसा कुछ। एक संदर्भ गणना करने के लिए थोड़ा असामान्य है पॉइंटर प्रकार आरसीएड पीआरटी विनाशक में इंगित ऑब्जेक्ट को स्वचालित रूप से हटा नहीं देता है। लेकिन ऐसा लगता है कि यह नग्न पॉइंटर्स और आरसीड पॉइंटर्स को थोड़ा सा सुरक्षित बना सकता है।
लेकिन अभी तक इसे हटाने की कोई आवश्यकता नहीं है।
लेकिन फिर यह मेरे लिए हुआ: यदि ऑब्जेक्ट की ओर इशारा किया गया है, तो पॉइंटी जानता है कि इसका संदर्भ गिना जा रहा है, उदा। यदि गिनती ऑब्जेक्ट (या किसी अन्य तालिका में) के अंदर है, तो नियमित delete_if_rc0 पॉइंट ऑब्जेक्ट का एक तरीका हो सकता है, न कि (स्मार्ट) पॉइंटर।
class Pointee {
private:
int rc;
...
public:
void delete_if_rc0() {
this->rc--;
if(this->rc == 0) {
delete this;
}
}
}
};
वास्तव में, यह बिल्कुल एक सदस्य विधि होने की जरूरत नहीं है, लेकिन एक नि: शुल्क समारोह हो सकता है:
map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
void* tptr = (void*)ptr;
if(keepalive_map[tptr] == 1) {
delete ptr;
}
};
(Btw, मैं जानता हूँ कि कोड बहुत सही नहीं है - यह हो जाता है यदि मैं सभी विवरण जोड़ता हूं तो कम पठनीय, इसलिए मैं इसे इस तरह से छोड़ रहा हूं।)
मुख्य समस्या यह होगी कि यदि आप इसे हटाते हैं तो आपके पास है उस वर्ग की वस्तुओं को बनाने के लिए कक्षा और आवंटन विधि के बीच एक तंग युग्मन बनाया। यह ओओ डिजाइन बहुत खराब है, क्योंकि ओओपी में सबसे मौलिक चीज स्वायत्त वर्ग बनाना है जो उनके कॉलर के बारे में नहीं जानते या उनकी परवाह नहीं करते हैं। इस प्रकार एक उचित ढंग से डिज़ाइन किया गया क्लास यह नहीं जानता कि उसे आवंटित किया गया था या नहीं। यदि आपको किसी कारण से ऐसी असाधारण तंत्र की आवश्यकता है, तो मुझे लगता है कि एक बेहतर डिजाइन वास्तविक वर्ग के चारों ओर एक रैपर वर्ग का उपयोग करना होगा, और रैपर को आवंटन के साथ सौदा करने दें। – Lundin