2011-01-24 13 views
12

एक नौसिखिया सवाल: मैं कुछ आभासी कार्यों के साथ वर्गों के एक पदानुक्रम है और मैं एक कारखाने विधि लागू करने के लिए कोशिश कर रहा हूँ, लेकिन मुझे यकीन है कि सबसे अच्छा तरीका है क्या नहीं कर रहा हूँ:सी ++ में फैक्ट्री विधि को लागू करने का पसंदीदा तरीका क्या है?

  1. वापसी कारखाने से एक कच्चे सूचक विधि और इसे कॉलिंग विधि में एक स्मार्ट सूचक में लपेटें
  2. फैक्टरी
  3. फैक्टरी से एक उचित वस्तु वापस लौटें (लेकिन क्या यह व्युत्पन्न कक्षा को सही ढंग से कॉपी करने जा रहा है?) और इसे असाइन करें कॉलिंग विधि में स्थानीय ऑब्जेक्ट
  4. फैक्ट्री से एक संदर्भ लौटाएं (लेकिन कैसे बनाएं मेमोरी लीक के बिना फैक्ट्री विधि में ऑब्जेक्ट?)

मैं फैक्ट्री विधि और एक न्यूनतम क्लाइंट के उदाहरण के लिए आभारी हूं, जो प्रभावी है और स्मृति को रिसाव नहीं करता है।

मेरी पृष्ठभूमि सी # और जावा है, इसलिए मैं सी ++ एटीएम में मेमोरी प्रबंधन के साथ थोड़ा सा खो गया हूं।

उत्तर

8

विकल्प 3 और 4 शुरुआत से बाहर हैं क्योंकि वे बस काम नहीं करते हैं: 3 ऑब्जेक्ट स्लाइस करता है, 4 मेमोरी लीक या अमान्य संदर्भ बनाता है।

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

बेशक, वैकल्पिक 5 है: कच्चे पॉइंटर्स और कचरा कलेक्टर का उपयोग करें।

+0

लगातार 'boost :: shared_ptr' लौटने से वास्तव में एक अच्छा विचार होता है। और यह इतना दर्द नहीं है (कच्चे पॉइंटर्स से कम से कम दर्द)। चूंकि अधिकांश बहुलक पदानुक्रम गैर-प्रतिलिपि वस्तुओं से बना होते हैं (यानी जो 'क्लोन' विधि प्रदान नहीं करते हैं), साझा अर्थशास्त्र अक्सर आप जो चाहते हैं। यद्यपि चक्रीय निर्भरता से सावधान रहें। –

+1

@Alexandre: मेरे अनुभव में, चक्रीय निर्भरता वास्तव में, वास्तव में दुर्लभ हैं। कम से कम जब आप घटनाओं/संकेतों का उपयोग नहीं कर रहे हैं। और वहां कमजोर संदर्भ (यानी सामान्य पॉइंटर्स) लगातार सबसे अच्छा समाधान हो सकता है। पता नहीं। कभी भी ई + ईमानदार होने के लिए सी ++ में ऐसा नहीं किया। –

+0

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

4

अच्छी तरह से मेरा स्वाद एक स्मार्ट सूचक लौटने के लिए जाता है। here उदाहरण सारणी का एक लिंक है जो एक स्मार्ट सूचक देता है।

my2c

3

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

+1

@ थॉमस एमसीएलओड: 'auto_ptr' का उपयोग करने में कोई ओवरहेड नहीं है, और एक बार C++ 0x एक' unique_ptr' में किक करता है। –

+0

@ मैट: शायद थोड़ा, लेकिन शून्य नहीं। – ThomasMcLeod

+0

@ थॉमस एमसीएलओड: मैं शून्य बनाए रखता हूं। विशिष्ट कार्यान्वयन, 'auto_ptr' सिर्फ एक सूचक है। इसके विनाशक आमंत्रण के लिए एक चेक की आवश्यकता होती है ... सिवाय इसके कि संकलक यह अनावश्यक साबित कर सकता है (उदाहरण: आप ऑब्जेक्ट तक पहुंचते हैं, तो इसका मतलब है कि पॉइंटर गैर-शून्य है, अन्यथा आपने अपरिभाषित व्यवहार का आह्वान किया है)। और इस प्रकार विनाशक हटाने के लिए एक कॉल बन जाता है, जिसे आपने वैसे भी किया होगा। ओह और मैं स्पष्ट रूप से एनआरवीओ भूल गया, ताकि प्रक्रिया में कोई प्रति शामिल न हो। मन, मुझे नहीं पता कि कोई संकलक उपयोगकर्ता की पहुंच के आधार पर गैर-शून्य पॉइंटर्स मानने के लिए पर्याप्त "बुरा" है, लेकिन यह निंदा की जाती है। –

1

आपको मेमोरी प्रबंधन की आवश्यकता है, कोई अन्य व्यवहार्य विकल्प नहीं है। हालांकि आपको फैक्ट्री विधि के भीतर से मेमोरी प्रबंधन की आवश्यकता नहीं हो सकती है।

स्मार्ट पॉइंटर्स के साथ मुख्य मुद्दा उनकी कॉन्वर्सिस की अनुपस्थिति है, जो clone वर्चुअल विधि को लागू करते समय दर्द होता है। दुर्भाग्य से C++ 0x में covariance नियम को आराम नहीं किया गया है, इसलिए यह एक मुद्दा बना हुआ है।

दूसरी तरफ, कच्चे सूचक को लौटने और इसे लपेटने के लिए इसे कॉलर तक छोड़कर, बग का दरवाजा खोल रहा है (भले ही यह दृष्टिकोण क्लोन के लिए चुने गए दृष्टिकोण है)।

व्यक्तिगत रूप से, मेरा सुझाव है:

  • कुख्यात auto_ptr या एक सादे सूचक है कि फोन करने वाले में लपेट चाहिए सी ++ 03
  • एक unique_ptr जैसे ही अपने संकलक यह हो जाता है के रूप में

उत्तरार्द्ध सबसे अधिक फायदे जोड़ता है (कोविरिएंस को छोड़कर), और इसमें कोई प्रदर्शन ओवरहेड नहीं है।

0

विधि 1 के साथ संघर्ष करने के बाद, मैं आपको लगता है कि विधि 2, आश्वस्त कर सकते हैं या तो लौटने boost::shared_ptr या boost::scoped_ptr (आमतौर पर पूर्व तुम क्या चाहते है, तो आप std::unique_ptr की पहुंच है नहीं है) है कि मैं क्या तहे दिल से recommand।

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

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