2011-11-19 17 views
9

कक्षा पदानुक्रम में कई वर्गों के बीच किसी ऑब्जेक्ट का उदाहरण साझा करने का एक अच्छा तरीका क्या है? मैं निम्नलिखित स्थिति है:कक्षाओं के बीच ऑब्जेक्ट साझा करने का एक अच्छा तरीका क्या है?

class texture_manager; 

class world { 
    ... 
    std::vector<object> objects_; 
    skybox skybox_; 
} 

मैं वर्तमान में एक सिंगलटन के रूप में texture_manager लागू किया, और ग्राहकों के कोड में कहीं से भी अपने instancing विधि कॉल। texture_manager को एस objects_ वेक्टर द्वारा skybox_, और संभवतः अन्य कक्षाओं द्वारा भी उपयोग किया जाना चाहिए, जो कि world वर्ग का हिस्सा हो सकता है या नहीं। जैसा कि मैं अपने कोड में सिंगलेट्स के उपयोग को सीमित करने की कोशिश कर रहा हूं, क्या आप इस दृष्टिकोण के किसी भी विकल्प की अनुशंसा करते हैं? एक समाधान जो दिमाग में आया था, उसे texture_manager संदर्भ को उन सभी वर्गों के रचनाकारों के लिए एक तर्क के रूप में पारित करना होगा, जिनके लिए इसकी आवश्यकता है। धन्यवाद।

+1

क्यों न केवल अपने texture_manager का वैश्विक उदाहरण घोषित करें? यदि वे सही ढंग से संभाले जाते हैं तो ग्लोबल्स बुरा नहीं होते हैं। और वे किसी भी अन्य उदाहरण के लिए किसी भी अन्य उदाहरण के आसपास थ्रेड किए गए पर्यावरण में कम या ज्यादा खतरनाक नहीं हैं ... – Mordachai

उत्तर

10

उस प्रश्न का सामान्य उत्तर ::std::shared_ptr का उपयोग करना है। या यदि आपके पास यह नहीं है, ::std::tr1::shared_ptr, या यदि आपके पास यह नहीं है, तो ::boost::shared_ptr

अपने विशेष मामले में, मैं कुछ अलग तरीकों में से एक की सिफारिश करेंगे:

  1. एक संभावना है, ज़ाहिर है, shared_ptr दृष्टिकोण। आप मूल रूप से ऑब्जेक्ट की आवश्यकता वाले सभी को अपने पॉइंटर के पास पास करते हैं, और जब उनमें से किसी को भी इसकी आवश्यकता नहीं होती है तो यह स्वचालित रूप से नष्ट हो जाती है। यद्यपि यदि आपका बनावट प्रबंधक उस पर इशारा करते हुए पॉइंटर्स के साथ समाप्त होने जा रहा है, तो आप एक संदर्भ चक्र बना रहे हैं, और इसे बहुत सावधानी से संभालना होगा।

  2. एक और संभावना यह है कि इसे स्थानीय चर के रूप में main में घोषित करें और इसे सभी के लिए एक सूचक या संदर्भ के रूप में पास करें। यह तब तक नहीं जायेगा जब तक आपका प्रोग्राम इस तरह से समाप्त नहीं हो जाता है, और आपको जीवन भर के प्रबंधन के बारे में चिंता करने की ज़रूरत नहीं है। इस मामले में एक नंगे सूचक या संदर्भ ठीक है।

  3. एक तीसरी संभावना एक सिंगलटन की तरह किसी तरह के अस्पष्ट स्वीकार्य उपयोगों में से एक है। और यह एक विस्तृत स्पष्टीकरण के हकदार है।

आप एक सिंगलटन बनाते हैं जो केवल काम करने के लिए उपयोगी पॉइंटर्स को सौंपना है। इसमें एक महत्वपूर्ण विशेषता है जो यह बताने की क्षमता है कि पॉइंटर को किस चीज को सौंपना है। यह एक वैश्विक विन्यास योग्य कारखाने की तरह है।

यह आपको सामान्य रूप से सिंगलटन के साथ बनाए गए विशाल परीक्षण मुद्दों से बचने की अनुमति देता है। चीजों का परीक्षण करने के लिए समय आने पर बस एक स्टब ऑब्जेक्ट को पॉइंटर को सौंपने के लिए कहें।

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

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


व्यक्तिगत रूप से, आपके मामले में, मैं दृष्टिकोण # 2 की सिफारिश करेंगे, बस main में स्टैक पर इसे बनाने और जहाँ भी यह आवश्यक है करने के लिए एक सूचक में गुजर। यह आपको अपने कार्यक्रम की संरचना के बारे में अधिक सावधानी से सोचने देगा, और इस प्रकार की वस्तु शायद आपके पूरे कार्यक्रम के जीवनकाल के लिए भी रहनी चाहिए।

+2

मुझे लगता है कि यहां कुछ प्रकार के साझा पॉइंटर का उपयोग करना मुश्किल (लेकिन महत्वपूर्ण) के आसपास टिप-टोइंग का एक तरीका है। वास्तव में 'texture_manager' ऑब्जेक्ट का मालिक कौन है इसके बारे में चर्चा। क्या इसे वास्तव में नष्ट कर दिया जाना चाहिए जैसे ही किसी के पास इसका कोई संदर्भ नहीं है? –

+1

मैंने इसके बारे में सोचा, हालांकि कक्षा पदानुक्रम के नीचे एक साझा_पीआरआर पास करना बोझिल लगता है, और मैं एक वैकल्पिक समाधान खोजने की उम्मीद कर रहा हूं। या यह आपके मन में क्या नहीं था? –

+0

@ फ्रैरिचराबे: हाँ, मैंने बस इसे 'मानक सलाह' के पहले कट के रूप में रखा है। इस सवाल ने तुरंत मुझे क्या सोचा। लेकिन मैंने इसे थोड़ा और गहराई से विश्लेषण किया और मेरा जवाब अपडेट किया। – Omnifarious