लगभग कोई नहीं, हालांकि यह वास्तव में एक अजीब जवाब है, और शायद सभी के लिए उपयुक्त कहीं नहीं है।
लेकिन मैंने अपने व्यक्तिगत मामले में एक विशेष प्रकार के सभी उदाहरणों को एक केंद्रीय, रैंडम-एक्सेस सीक्वेंस (थ्रेड-सेफ) में संग्रहीत करने के लिए, और इसके बजाय 32-बिट सूचकांकों (सापेक्ष पते, अर्थात) के साथ काम करने के लिए इसे और अधिक उपयोगी पाया है। बल्कि निरपेक्ष संकेत की तुलना में।
एक शुरुआत के लिए:
- यह 64-बिट प्लेटफार्मों पर एनालॉग पॉइंटर की मेमोरी आवश्यकताओं को आधा कर देता है। अब तक मुझे किसी विशेष डेटा प्रकार के ~ 4.29 बिलियन से अधिक उदाहरणों की आवश्यकता नहीं है।
- यह सुनिश्चित करता है कि किसी विशेष प्रकार के सभी उदाहरण
T
, कभी भी स्मृति में बिखरे हुए नहीं होंगे। यह सभी प्रकार के एक्सेस पैटर्न के लिए कैश मिस को कम करने के लिए जाता है, यहां तक कि पेड़ों की तरह जुड़े संरचनाओं को भी खोदता है यदि नोड्स को सूचक के बजाय सूचक का उपयोग करके एक साथ जोड़ा जाता है।
- समानांतर डेटा पेड़ों या हैश तालिकाओं के बजाय सस्ते समानांतर सरणियों (या विरल सरणियों) का उपयोग करना आसान हो जाता है।
- समानांतर चौराहे पर सेट चौराहों को रैखिक-समय पर या बेहतर उपयोग करके कहा जा सकता है।
- हम सूचकांक को क्रमबद्ध कर सकते हैं और एक बहुत ही कैश-फ्रेंडली अनुक्रमिक एक्सेस पैटर्न प्राप्त कर सकते हैं।
- हम इस बात पर नज़र रख सकते हैं कि किसी विशेष डेटा प्रकार के कितने उदाहरण आवंटित किए गए हैं।
- उन स्थानों की संख्या को कम करता है जिन्हें अपवाद-सुरक्षा जैसी चीजों से निपटना पड़ता है, अगर आप उस तरह की परवाह करते हैं।
उस ने कहा, सुविधा एक नकारात्मक पहलू है और साथ ही प्रकार की सुरक्षा भी है। हम कंटेनर और इंडेक्स दोनोंT
तक पहुंच के बिना इंस्टेंस का उपयोग नहीं कर सकते । और एक पुराना पुराना हमें बताता है कि वह किस प्रकार का डेटा संदर्भित करता है, इसलिए कोई प्रकार की सुरक्षा नहीं है। हम गलती से किसी इंडेक्स का उपयोग करके एक्सेस करने का प्रयास कर सकते हैं । दूसरी समस्या को कम करने के लिए मैं अक्सर इस तरह की बात करता हूं:int32_t
Bar
Foo
struct FooIndex
{
int32_t index;
};
जो एक तरह से मूर्खतापूर्ण लगता है, लेकिन यह मुझे प्रकार की सुरक्षा वापस देता है ताकि लोग गलती Bar
से Foo
एक संकलक त्रुटि के बिना एक सूचकांक के माध्यम से एक्सेस करने का प्रयास न कर सकें । सुविधा पक्ष के लिए, मैं बस थोड़ी सी असुविधा को स्वीकार करता हूं।
एक और बात जो लोगों के लिए एक बड़ी असुविधा हो सकती है, वह यह है कि मैं ओओपी-शैली के वंशानुक्रम-आधारित बहुरूपता का उपयोग नहीं कर सकता, क्योंकि यह एक आधार सूचक के लिए कॉल करेगा जो विभिन्न आकार और संरेखण आवश्यकताओं के साथ सभी प्रकार के विभिन्न उपप्रकारों को इंगित कर सकता है। लेकिन मैं इन दिनों इनहेरिटेंस का अधिक उपयोग नहीं करता - ईसीएस दृष्टिकोण को प्राथमिकता दें।
के रूप में shared_ptr
, मैं इसे इतना उपयोग नहीं करने की कोशिश करता हूं। ज्यादातर समय मुझे नहीं लगता कि यह स्वामित्व साझा करने के लिए समझ में आता है, और इतनी जल्दबाजी करने से तार्किक लीक हो सकती है। अक्सर कम से कम उच्च स्तर पर, एक चीज एक चीज से संबंधित होती है। जहाँ मुझे अक्सर यह पता चलता है कि इसका उपयोग करने का प्रलोभन उन shared_ptr
स्थानों में किसी वस्तु के जीवनकाल का विस्तार कर रहा है जो वास्तव में स्वामित्व के साथ सौदा नहीं करते थे, जैसे कि थ्रेड समाप्त होने से पहले ऑब्जेक्ट को नष्ट नहीं किया जाता है यह सुनिश्चित करने के लिए धागे में सिर्फ एक स्थानीय फ़ंक्शन। उसका इस्तेमाल कर रहे हैं।
उस समस्या से निपटने के लिए, shared_ptr
GC या उसके जैसे कुछ का उपयोग करने के बजाय , मैं अक्सर थ्रेड पूल से चलने वाले अल्पकालिक कार्यों का पक्ष लेता हूं, और ऐसा करता हूं कि अगर वह धागा किसी वस्तु को नष्ट करने का अनुरोध करता है, तो वास्तविक विनाश एक सुरक्षित के लिए स्थगित कर दिया जाता है वह समय जब सिस्टम यह सुनिश्चित कर सकता है कि किसी भी प्रकार को ऑब्जेक्ट ऑब्जेक्ट प्रकार तक पहुंचने की आवश्यकता नहीं है।
मैं अब भी कभी-कभी रेफ-काउंटिंग का उपयोग करता हूं, लेकिन इसे अंतिम उपाय की रणनीति की तरह मानता हूं। और कुछ मामले हैं जहां यह वास्तव में स्वामित्व को साझा करने के लिए समझ में आता है, एक निरंतर डेटा संरचना के कार्यान्वयन की तरह, और मुझे लगता है कि यह सही अर्थों में shared_ptr
दूर तक पहुंचने के लिए सही अर्थ बनाता है।
तो वैसे भी, मैं ज्यादातर सूचकांकों का उपयोग करता हूं, और कच्चे और स्मार्ट दोनों प्रकार के संयम का उपयोग करता हूं। मुझे सूचकांक पसंद हैं और वे प्रकार के दरवाजे खुलते हैं जब आप जानते हैं कि आपकी वस्तुओं को आकस्मिक रूप से संग्रहीत किया जाता है, और मेमोरी स्पेस में बिखरे हुए नहीं हैं।