2009-12-09 20 views
8

क्या कोई सरल, कुशल कमजोर/संरक्षित पॉइंटर है? मुझे एक ही ऑब्जेक्ट पर एकाधिक पॉइंटर्स चाहिए जो ऑब्जेक्ट हटा दिए जाने पर सभी स्वचालित रूप से NULL पर सेट हो जाते हैं। एक "मास्टर" पॉइंटर होता है जिसे ऑब्जेक्ट को हटाने के लिए हमेशा उपयोग किया जाता है, लेकिन कई अन्य पॉइंटर्स हो सकते हैं जो एक ही ऑब्जेक्ट को संदर्भित करते हैं।सरल, कुशल कमजोर पॉइंटर जो लक्ष्य स्मृति को हटा दिया जाता है जब NULL पर सेट किया जाता है

यहाँ कुछ समाधान है कि काफी मेरी जरूरतों से मेल नहीं खाते हैं:

  • QPointer: मैं एक क्यूटी एप्लिकेशन विकसित करने नहीं कर रहा हूँ; मैं QObject से यह libary/derive शामिल नहीं करना चाहता।
  • boost::weak_ptr: एक हटाए गए ऑब्जेक्ट तक पहुंचने पर अपवाद फेंक दिया जाता है। मेरी स्थिति के लिए बहुत महंगा: कमजोर सूचक का परीक्षण करना सामान्य होना चाहिए; जब कोई कमजोर सूचक अब मान्य नहीं होता है तो मैं कुछ मैन्युअल क्लीन-अप करने की योजना बना रहा हूं।अद्यतन: weak_ptr फेंक अपवाद
  • Low-Overhead Weak Pointers बिना परीक्षण किया जा सकता: यह बहुत है कि मैं क्या देख रहा हूँ के करीब है, सिवाय मैं इस तथ्य "यह योजना केवल जब तक आप डॉन 'के रूप में काम करने के लिए गारंटी है पसंद नहीं है टी एक ही स्थान पर 2 ** आकार (int) बार आवंटित करें। "

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

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

मैं सी ++ में विकास कर रहा हूं।

+0

एक सामान्य प्रश्न होगा, "क्या एक खेल विकसित करने के लिए क्यूटी सही विकल्प है?" –

+3

बूस्ट का कमजोर पॉइंटर आपको यह जांचने की अनुमति देता है कि यह मान्य है या नहीं। यह केवल अपवाद फेंकता है यदि आप सीधे इसे अस्वीकार करने का प्रयास करते हैं - यदि आप एक शून्य सूचक को हटाना चाहते हैं तो क्या होता है। – jalf

+0

सी ++ 11 में ['std :: weak_ptr'] है (http://en.cppreference.com/w/cpp/memory/weak_ptr)। बूस्ट से एक जैसा दिखता है। – Palec

उत्तर

16

आप के lock() सदस्य का उपयोग weak_ptr के मानों का परीक्षण किए बिना (फिर उपयोग) करने के लिए अपवादों के निपटारे के बिना कर सकते हैं।

10

यह गेम विकास में एक आम बात है। आम तौर पर कमजोर पॉइंटर्स को बढ़ावा देने के बजाए ऑब्जेक्ट हैंडल की एक प्रणाली का उपयोग किया जाता है, क्योंकि हमें अंतर्निहित लुकअप टेबल को निरंतर स्मृति होने की आवश्यकता होती है और क्योंकि कभी-कभी हमें कुछ अतिरिक्त जानकारी या गारंटी की आवश्यकता होती है जो बूस्ट नहीं मिला है।

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

struct handle_t 
{ 
    uint32 serialnumber; // this is a GUID for each entity; it increases 
         // monotonically over the life of the process 
    uint entityindex; 
    inline Entity *Get(); 
} 

struct entityinfo_t 
{ 
    Entity *pEntity; // an entity's destructor NULLs this out on deletion 
    uint32 serialnumber; 
} 

entityinfo_t g_EntityTable[MAX_ENTITIES]; 

Entity *handle_t::Get() 
{ 
    entityinfo_t &info = g_EntityTable[entityIndex]; 
    if (serialnumber == info.serialnumber) 
    { 
    return info.pEntity; 
    } 
    else 
    { 
     return NULL; 
    } 
} 

सीरियल नंबर आवश्यक है, क्योंकि सरणी लगातार आकार की है - अंत में, आप इकाई तालिका प्रविष्टियों पुनरावृत्ति करने के लिए की आवश्यकता होगी, और वहाँ एक संभावना है कि आप के लिए, कहते हैं, # 743 सूचकांक एक हैंडल संग्रहीत कर सकता है है, काफी लंबा है कि ऑब्जेक्ट हटा दिया गया है और सेल # 743 किसी और चीज़ के लिए पुन: उपयोग किया गया है।यदि आपके पास पॉइंटर्स की सूची में केवल पॉइंटर था, तो आप एक हैंडल को समाप्त कर देंगे जो न्यूल जाने के बजाय पूरी तरह से अलग ऑब्जेक्ट को इंगित करता है। इसलिए, हम प्रत्येक इकाई को विश्व स्तर पर अद्वितीय संख्या देते हैं और स्टोर को भी संभालते हैं।

आप निश्चित रूप से इकाई तालिका के लिए एक स्टडी वेक्टर या नक्शा या एक शब्दकोश या किसी अन्य प्रकार की डेटा संरचना का उपयोग कर सकते हैं, लेकिन हमारी आवश्यकताओं को आम तौर पर निरंतर स्मृति, कैश कोहिरेंसी, और पूर्ण अधिकतम प्रदर्शन के लिए किया गया है (क्योंकि handle_t :: प्राप्त करें() प्रति फ्रेम हजारों बार बुलाया जाता है)।

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

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