2011-02-02 7 views
5

मैं वर्तमान में सी ++ में एक गेम पर काम कर रहा हूं। चूंकि कोई कचरा कलेक्टर नहीं है, इसलिए हमेशा वस्तुओं को ध्यान से हटाने के लिए हमेशा यह सुनिश्चित किया जाता है कि हटाए जाने के बाद ऐसी वस्तुओं को और अधिक एक्सेस नहीं किया जाता है।
अब एक परियोजना बढ़ने के साथ ही कुछ वस्तुओं को अधिक से अधिक स्थानों से संदर्भित किया जा सकता है। उदाहरण के लिए, गेम में मेरी इकाइयां रेंडरर से संदर्भ पदानुक्रम से, चयन तंत्र से, एचयूडी से और इसी तरह से संदर्भित हो सकती हैं। अब - यदि कोई ऑब्जेक्ट हटा दिया जाता है तो किसी को यह सुनिश्चित करना होगा कि इस ऑब्जेक्ट को संदर्भित करने वाले सभी अन्य वर्गों को इसके बारे में अधिसूचित किया जाएगा।
या आइए इसे दूसरी तरफ कहें - अगर मैं एक नई कक्षा बनाता हूं जो मेरी इकाइयों में से किसी एक को संदर्भित कर सकता है, तो मुझे इकाई के कोड को भी बदलना होगा (या यूनिट मैनेजर या जो भी मॉड्यूल इकाई को हटा देता है यह नष्ट हो जाता है) यह सुनिश्चित करने के लिए कि यह नया मॉड्यूल जानता है कि वर्तमान इकाई जो वर्तमान इकाई संदर्भित करती है उसे हटा दिया जाता है।क्या यह एक योग्य सॉफ्टवेयर डिज़ाइन है?

अब मैं थोगट एक सामान्य घटना संचालित हो सकता हूं जो इस समस्या को हल करने के लिए आधारभूत आधार तैयार कर सकता है जिस पर एक और वस्तु सब्सक्राइब कर सकती है। कुछ इस तरह:

class DeletableBase;//forward declaration 

class ISubscriber{ 
public: 
    virtual someObjectGotDeleted(DeletableBase* deletedObject)=0; 
}; 

class DeletableBase{ 
private: 
    vector<ISubscriber*> subscribers; 
public: 
    virtual ~DeletableBase(){ 
     for(int i=0; i<subscribers.size(); i++) 
      subscribers[i]->someObjectGotDeleted(this); 
    } 
    subscribeForDeleteEvent(ISubscriber* subscriber){ 
     subscribers.push_back(subscriber); 
    } 
}; 
उस के साथ

- अगर मैं किसी भी वस्तु है कि एक नया वर्ग से इस वर्ग से विरासत संदर्भ मैं बस एक ग्राहक के रूप में अपने आप को जोड़ सकते हैं और अगर वस्तु किसी अन्य जगह से हटा दिया जाएगा मैं मिल जाएगा इसके बारे में अधिसूचित

यह कोडिंग का एक "साफ" तरीका है?

+2

http://codereview.stackexchange.com/ पर निर्भर करता है। हालांकि, मैं इसे 'ऑफ टॉपिक' के रूप में बंद नहीं करना चाहता हूं। :/ –

+1

मैं सहमत हूं; क्लोज स्क्रीन को उनके द्वारा सूचीबद्ध कुछ के अलावा साइटों पर माइग्रेट करने का विकल्प चाहिए। (मेटा के लिए!) –

+2

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

उत्तर

6

यदि यह पूरी तरह से स्मृति प्रबंधन (राज्य परिवर्तन के बजाए) के बारे में है, तो इसके बजाय एक स्मार्ट सूचक का उपयोग करें। shared_ptr के साथ शुरू करें, फिर make_shared/allocate_shared या boost::intrusive_ptr का उपयोग करके अनुकूलित करें यदि यह बहुत धीमी है।

+0

एचएम - लेकिन इसका मतलब है कि मैं प्रत्येक मॉड्यूल एक smartpointer के माध्यम से वस्तु (संदर्भ) प्रत्येक यात्रा कुछ की तरह में चेक इन करना होगा अगर मैं ऐसा ' अगर (myObj-> isStillAlive() == false) प्रतिक्रिया(); ' – Mat

+0

@Mat: ऐसा लगता है कि आप हमेशा (डिजाइन पैटर्न के बावजूद) ऑब्जेक्ट या पॉइंटर की वैधता को किसी भी तरीके से जांचने की आवश्यकता है। यदि आपके पास ऑब्जेक्ट करने के लिए पॉइंटर है जिसे हटाया जा सकता है (अमान्य) तो आपको ऑब्जेक्ट पर कोई कार्रवाई करने से पहले इसे जांचना होगा। यदि आपके पास एक ऐसा मॉड्यूल है जो ऑब्जेक्ट जीवनकाल को नियंत्रित करता है, तो आप अन्य मॉड्यूल से एक्सेस करते समय weak_ptr का उपयोग कर सकते हैं। हालांकि, आपको isewillAlive() – user396672

+0

@Mat: की जांच करने के बजाय someweakptr.lock() परिणाम की जांच करने की आवश्यकता है: एक 'बूस्ट :: shared_ptr' और कई' boost :: weak_ptr' का उपयोग करने पर विचार करें। –

1

एक बात आप पर विचार करने के (आप एक खेल में लिख रहे हैं, खासकर अगर) होगा कि जब आपके सदस्यता प्राप्त वस्तुओं में से एक मुख्य थ्रेड पर नष्ट कर दिया जाता है, अपने खेल सबसे अधिक संभावना ब्लॉक अपने ग्राहकों में से प्रत्येक के लिए किया जाता है जब तक जाएगा ऑब्जेक्ट को हटाने पर जो कुछ भी करने जा रहा है वह कर रहा है। यदि आप सावधान नहीं हैं तो यह गेम प्रदर्शन को प्रभावित कर सकता है।

0

आपको अन्य वस्तुओं द्वारा संदर्भित वस्तुओं को छोड़ने से बचना होगा, लेकिन दूसरी तरफ नहीं। Boost smart pointers आपके लिए 9 0% काम करेगा।

पी.एस .: सी के लिए ++ :-)

+0

आपके पहले वाक्यांश से आपका क्या मतलब है? मुझे पता है कचरा कलेक्टरों देखते हैं, लेकिन मैं iphone के लिए कोडिंग कर रहा हूँ और एक उच्च और निरंतर फ़्रेमरेट – Mat

+0

क्यों उद्देश्य सी, तो उपयोग नहीं की जरूरत है? – Dave

0

IMHO एक कचरा कलेक्टर नहीं है, आप अपने खुद स्मृति allocator को लागू करने की जरूरत है। प्रत्येक उदाहरण को देखने के बजाय, आप उदाहरण प्रकार या कक्षा के संबंध में जारी स्मृति का निरीक्षण कर सकते हैं। बेशक, इसके लिए, आपकी स्मृति आवंटक को देखा जाना चाहिए। पर्यवेक्षकों को अधिक प्रभावी ढंग से सूचित करने के लिए आप map या set डेटा संरचना या multi संस्करणों का उपयोग कर सकते हैं। जिसका अर्थ है, आपका मेमोरी मैनेजर मध्यस्थ और अवलोकन होगा।

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

+0

क्या आपका मतलब कुछ ऐसा है? 'MyMemoryManager :: सदस्यता के (इस, objectToObserve)' – Mat

+0

@Mat मुझे लगता है कि यह संभव है यदि आप 'ओवरलोड new' ऑपरेटर। साथ ही, आपको 'हटाएं' अधिभारित करने की आवश्यकता हो सकती है। –