2010-09-13 16 views
5

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

निम्नलिखित परिभाषा एपीआई से आते हैं:

typedef unsigned long shape_handle;  
shape_handle make_new_shape(int type); 

मैं make_new_shape को फिर से परिभाषित करने की जरूरत है और मैं shape_handle को फिर से परिभाषित करने का विकल्प है।

मैं इस संरचना (सरलीकृत) को परिभाषित किया है:

struct Shape 
{ 
    int type 
}; 

make_new_shape के कोलर Shape की अंतर्निहित संरचना के बारे में परवाह नहीं है, यह सिर्फ इतना है कि यह काम करता है कॉल कर सकते हैं एक यह करने के लिए "संभाल" की जरूरत है जैसे:

void `set_shape_color(myshape, RED);` 

जहां myshape आकार के लिए हैंडल है।

मेरे इंजन Shape वस्तुओं और अन्य आवश्यकताओं के लिए स्मृति का प्रबंधन करेगा हुक्म है कि इंजन एक सूची या अन्य iterable कंटेनर में Shape वस्तुओं के भंडारण किया जाना चाहिए।

मेरा सवाल यह है कि, इस हैंडल का प्रतिनिधित्व करने का सबसे सुरक्षित तरीका क्या है - यदि Shape स्वयं एक std :: सूची - एक इटरेटर, एक सूचक, एक अनुक्रमणिका में संग्रहीत किया जा रहा है?

+2

तुम क्यों एसटीडी चुना है :: सूची? –

+0

@jk - मैं कंटेनर के मध्य से जोड़ सकते हैं और Shape' वस्तुओं को हटाने 'करने में सक्षम होने की जरूरत है। – BeeBand

+0

आप निश्चित रूप से shape_handle (या make_new_shape) को फिर से परिभाषित नहीं करना चाहते हैं। –

उत्तर

3

जवाब यह दर्शाया है निर्भर करता है:

  • std::list के लिए, एक iterator (नहीं एक सूचक) उपयोग करें, क्योंकि एक iterator आप पूरी सूची चलने के बिना तत्व दूर करने के लिए अनुमति देता है।
  • std::map या boost::unordered_map के लिए,, Key

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

दोनों map और unordered_map बेंचमार्किंग एक तेजी से अपने मामले :) में है जो देखने के लिए प्रयास करें

6

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

तो, यदि आप बस अपने आकार तक पहुंचना चाहते हैं तो एक सूचक सबसे सरल होगा। यदि आप अपनी सूची के माध्यम से फिर से शुरू करना चाहते हैं तो एक इटरेटर का उपयोग करें।

एक सूची सूची में बेकार है क्योंकि std :: सूची [] ऑपरेटर को अधिभारित नहीं करती है।

+1

+1: चाहे आप अपने आंतरिक प्रतिनिधित्व (इटरेटर) तक पहुंच प्रदान करते हैं या नहीं (सूचक) सबसे महत्वपूर्ण अंतर है। –

3

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

यदि आप वेक्टर का उपयोग कर रहे थे, तो इटरेटर या पॉइंटर्स का उपयोग न करें, क्योंकि जब आप वैक्टर क्षमता को पार करते हैं तो तत्वों को स्थानांतरित किया जा सकता है, और आपके पॉइंटर्स/इटरेटर अमान्य हो जाएंगे।

यदि आप एक आंतरिक कंटेनर के बावजूद सुरक्षित प्रतिनिधित्व चाहते हैं, तो अपने आकार में पॉइंटर्स का एक कंटेनर (सूची/वेक्टर) बनाएं, और आकार पॉइंटर को अपने क्लाइंट पर वापस कर दें। भले ही कंटेनर स्मृति में चारों ओर ले जाया गया हो, आकार वस्तुएं एक ही स्थान पर रहेंगी।

3

Iterators संकेत अधिक सुरक्षित नहीं हैं, लेकिन वे कच्चे संकेत से ज्यादा बेहतर निदान अगर आप एक का उपयोग कर रहे है एसटीएल कार्यान्वयन की जांच की!

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

यदि आप एक पुनरावर्तक का उपयोग करते हैं और आपके पास एक एसटीएल कार्यान्वयन की जांच की जाती है, जैसे ही आप एक मिटाए गए तत्व को पुनरावर्तक तक पहुंचते हैं, तो आपको "इटरेटर अमान्य" जैसे संदेश मिलते हैं। ऐसा इसलिए है क्योंकि आपने जिस तत्व को इंगित किया है उसे मिटा दिया है। बूम, आपने बस खुद को पूरी तरह से डिबगिंग प्रयासों से बचाया है।

तो, हे के लिए नहीं सूचकांक (एन) प्रदर्शन। हमेशा iterators - संकेत और iterators के बीच!

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