जब आप पैरामीटर के साथ एक बनाते हैं तो डिफ़ॉल्ट पैरामीटर रहित निर्माता क्यों चला जाता है


161

C #, C ++ और जावा में, जब आप एक कंस्ट्रक्टर लेने वाले पैरामीटर बनाते हैं, तो डिफ़ॉल्ट पैरामीटरलेस एक चला जाता है। मैंने हमेशा सिर्फ इस तथ्य को स्वीकार किया है, लेकिन अब मैं यह सोचने लगा हूं कि क्यों।

इस व्यवहार का कारण क्या है? क्या यह सिर्फ एक "सुरक्षा उपाय / अनुमान" है "यदि आपने अपना खुद का एक निर्माता बनाया है, तो आप शायद यह नहीं चाहते हैं कि यह एक" फांसी हो? या क्या इसके पास एक तकनीकी कारण है जो कंपाइलर के लिए एक बार खुद को कंस्ट्रक्टर बनाने के बाद जोड़ना असंभव बना देता है?


7
आप C ++ को उन भाषाओं की सूची में जोड़ सकते हैं जिनके पास यह व्यवहार है।
हेंक होल्टरमैन

18
और C ++ में अब आप Foo() = default;डिफ़ॉल्ट को वापस पाने के लिए कह सकते हैं ।
एमएसलेटर

1
यदि मापदंडों के साथ आपका निर्माणकर्ता अपने सभी मापदंडों के लिए डिफ़ॉल्ट तर्क दे सकता है, तो यह अंतर्निहित पैरामीटर के साथ संघर्ष करेगा, इसलिए जब आप अपना निर्माण करते हैं, तो इसे हटाने की आवश्यकता होती है।
मोरेवेन

3
पहले कंपाइलर के संस्थापकों के बीच इस बहस के लिए उपस्थित होने की कल्पना करें कि डिफ़ॉल्ट कंस्ट्रक्टर की आवश्यकता है और गर्म चर्चा से वह प्रेरित होगा।
किंग्संगो

7
@HenkHolterman C ++ इस व्यवहार के साथ सिर्फ एक और नहीं है, लेकिन प्रवर्तक, और यह C संगतता की अनुमति देने के लिए है, जैसा कि द डिज़ाइन और इवोल्यूशन में Crou ++ द्वारा चर्चा की गई है और जैसा कि मेरे अद्यतन जवाब में संक्षेप में दिया गया है।
जॉन हन्ना

जवाबों:


219

ऐसा कोई कारण नहीं है कि कंपाइलर कंस्ट्रक्टर को जोड़ नहीं सकता है यदि आपने अपना जोड़ा है - तो कंपाइलर जो चाहे कर सकता है! हालाँकि, आपको यह देखना होगा कि सबसे अधिक समझ में क्या आता है:

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

इसलिए, प्रत्येक मामले में, आप देख सकते हैं कि वर्तमान संकलक का व्यवहार कोड के संभावित इरादे को संरक्षित करने के संदर्भ में सबसे अधिक समझ में आता है ।


2
मुझे लगता है कि आपके उत्तर का बाकी हिस्सा आपके पहले वाक्य को गलत साबित करता है।
कोनराड रुडोल्फ

76
@KonradRudolph, पहला वाक्य कहता है कि एक कंपाइलर इस परिदृश्य में एक कंस्ट्रक्टर जोड़ सकता है - बाकी का उत्तर बताता है कि यह क्यों नहीं है (प्रश्न में निर्दिष्ट भाषाओं के लिए)
जॉनएल

1
नहीं। यदि हमने एक OO भाषा को खरोंच से डिज़ाइन किया है, तो इसका कोई स्पष्ट अर्थ नहीं है कि कोई निर्माता नहीं है, "आपने एक निर्माणकर्ता को जोड़ने की उपेक्षा की है जो वर्ग को 'अपरिवर्तनीय" सुनिश्चित करता है और यह एक संकलन त्रुटि को बढ़ाएगा।
जॉन हैना

70

निश्चित रूप से कोई तकनीकी कारण नहीं है कि भाषा को इस तरह से डिजाइन करना है।

कुछ चार-यथार्थवादी विकल्प हैं जिन्हें मैं देख सकता हूं:

  1. कोई भी डिफ़ॉल्ट निर्माता नहीं है
  2. वर्तमान परिदृश्य
  3. हमेशा डिफ़ॉल्ट रूप से एक डिफ़ॉल्ट कंस्ट्रक्टर प्रदान करता है, लेकिन इसे स्पष्ट रूप से दबाने की अनुमति देता है
  4. हमेशा एक डिफ़ॉल्ट कंस्ट्रक्टर प्रदान किए बिना इसे दबाए रखने की अनुमति देता है

विकल्प 1 कुछ हद तक आकर्षक है, इसमें जितना अधिक मैं कम बार कोड करता हूं, मैं वास्तव में एक पैरामीटर रहित निर्माता चाहता हूं । किसी दिन मुझे सिर्फ यह गिनना चाहिए कि मैं वास्तव में एक डिफ़ॉल्ट कंस्ट्रक्टर का उपयोग कैसे करता हूं ...

विकल्प 2 मैं ठीक हूं।

विकल्प 3 भाषा के बाकी हिस्सों के लिए जावा और सी # दोनों के प्रवाह के खिलाफ जाता है। जब तक आप स्पष्ट रूप से "निजी" चीजों को "हटा" नहीं देते, जब तक कि आप जावा में डिफ़ॉल्ट रूप से चीजों को अधिक निजी रूप से नहीं बनाते हैं।

विकल्प 4 भयानक है - आप बिल्कुल कुछ मापदंडों के साथ निर्माण को बाध्य करने में सक्षम होना चाहते हैं। क्या new FileStream()मतलब होगा ?

इसलिए मूल रूप से, यदि आप इस आधार को स्वीकार करते हैं कि एक डिफ़ॉल्ट कंस्ट्रक्टर प्रदान करना बिल्कुल सही है, तो मेरा मानना ​​है कि जैसे ही आप अपने खुद के कंस्ट्रक्टर प्रदान करते हैं, तो इसे दबाने के लिए बहुत अधिक समझ में आता है।


1
मुझे विकल्प 3 पसंद है, क्योंकि जब मैं कुछ लिख रहा होता हूं, तो मुझे दोनों प्रकार के कंस्ट्रक्टरों की आवश्यकता होती है और फिर पैरामीटर के साथ सिर्फ कंस्ट्रक्टर। इसलिए मैं दिन में एक बार कुछ पैरामीटर रहित कंस्ट्रक्टर को निजी बनाऊंगा और फिर दिन में 10 बार पैरामीटर्सलेस कंस्ट्रक्टर लिखूंगा। लेकिन यह शायद सिर्फ मुझे है, मैं बहुत सीरियजेबल कक्षाएं लिख रहा हूं ...
पेट्र मेंसिक

8
@PetrMensik: यदि आपके पैरामीटरलेस कंस्ट्रक्टर को वास्तव में कुछ भी नहीं करने की आवश्यकता है, तो यह एक-लाइनर है जो निश्चित रूप से "स्पष्ट निष्कासन" कथन की तुलना में बहुत अधिक कोड नहीं लेगा।
जॉन स्कीट

2
@PetrMensik: क्षमा करें, मेरी गलती है, हाँ। यह निश्चित रूप से मेरे अनुभव के विपरीत है - और मैं तर्क दूंगा कि कुछ सहित स्वचालित रूप से अधिक खतरनाक विकल्प भी है ... यदि आप गलती से इसे नहीं छोड़ते हैं, तो आप अपने आक्रमणकारियों को पेंच कर सकते हैं
जॉन स्कीट

2
# 4 structबेहतर या बदतर के लिए सी # मामला है ।
19 बाज़ में 19

4
मुझे विकल्प 1 पसंद है क्योंकि इसे समझना आसान है। कोई "मैजिक" कंस्ट्रक्टर जिसे आप कोड में नहीं देख सकते। विकल्प 1 के साथ कंपाइलर को एक वार्निग का उत्सर्जन करना चाहिए जब (या शायद यहां तक ​​कि अस्वीकृत हो?) एक गैर-स्थिर वर्ग के पास कोई उदाहरण नहीं है। कैसे के बारे में: "कक्षा के लिए कोई उदाहरण निर्माता नहीं मिला <TYPE>। क्या आपको कक्षा को स्थिर घोषित करने का मतलब है?"
जेपी स्टिग नीलसन

19

संपादित करें। वास्तव में, जबकि मैं अपने पहले उत्तर में जो कहता हूं वह मान्य है, यही वास्तविक कारण है।

शुरुआत में सी। सी। ऑब्जेक्ट-ओरिएंटेड नहीं था (आप एक ओओ दृष्टिकोण ले सकते हैं, लेकिन यह आपकी मदद नहीं करता है या कुछ भी लागू नहीं करता है)।

तब सी विथ क्लासेस था, जिसे बाद में सी ++ नाम दिया गया था। C ++ ऑब्जेक्ट-ओरिएंटेड है, और इसलिए एनकैप्सुलेशन को प्रोत्साहित करता है, और किसी ऑब्जेक्ट के अपरिवर्तन को सुनिश्चित करता है - किसी भी विधि के आरंभ और अंत में, ऑब्जेक्ट एक मान्य स्थिति में है।

इसके साथ स्वाभाविक बात यह है कि, यह सुनिश्चित करने के लिए एक वर्ग हमेशा एक निर्माता होना चाहिए कि यह एक वैध स्थिति में शुरू हो - अगर कंस्ट्रक्टर को यह सुनिश्चित करने के लिए कुछ भी करने की ज़रूरत नहीं है, तो खाली निर्माता इस तथ्य का दस्तावेजीकरण करेगा। ।

लेकिन सी ++ के साथ एक लक्ष्य सी के साथ संगत होना था कि जितना संभव हो सके, सभी वैध सी प्रोग्राम भी मान्य थे सी ++ प्रोग्राम (अब सक्रिय लक्ष्य के रूप में नहीं है, और सी ++ के अलग-अलग विकास का मतलब है कि यह अब नहीं रखता है। )।

इसका एक प्रभाव कार्यक्षमता के बीच structऔर में दोहराव था class। पूर्व करने वाली चीजें C रास्ता (सब कुछ सार्वजनिक रूप से डिफ़ॉल्ट) और बाद में कर रही चीजें अच्छे OO तरीके से (सब कुछ डिफ़ॉल्ट रूप से निजी, डेवलपर सक्रिय रूप से सार्वजनिक करता है कि वे क्या चाहते हैं)।

एक और यह है कि एक सी के लिए struct, जिसमें एक कंस्ट्रक्टर नहीं हो सकता है क्योंकि सी में कंस्ट्रक्टर नहीं हैं, सी ++ में मान्य हैं, फिर इसे देखने के लिए सी ++ के लिए एक अर्थ होना चाहिए। और इसलिए, जब एक कंस्ट्रक्टर नहीं होता है, तो यह सुनिश्चित करता है कि ओ ओ प्रैक्टिस को सुनिश्चित करने के लिए सक्रिय रूप से एक अशुभ सुनिश्चित करता है, सी ++ ने इसका मतलब यह निकाला कि एक डिफ़ॉल्ट पैरामीटर रहित कंस्ट्रक्टर था जो काम करता था जैसे यह एक खाली शरीर था।

सभी C structsअब वैध C ++ थे structs, (जिसका अर्थ था कि वे C ++ जैसे ही classesसब कुछ हैं - सदस्य और विरासत - जनता) बाहर से इलाज किया जाता है जैसे कि यह एक एकल, पैरामीटर रहित निर्माता था।

यदि फिर भी आपने एक classया एक कंस्ट्रक्टर को रखा है struct, तो आप सी के बजाय C ++ / OO तरीके से काम कर रहे थे, और डिफ़ॉल्ट कंस्ट्रक्टर की कोई आवश्यकता नहीं थी।

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

इसलिए जब जावा साथ आया (कई तरह से C ++ पर आधारित) और बाद में C # (C ++ और जावा पर अलग-अलग तरीकों से आधारित), तो उन्होंने इस दृष्टिकोण को रखा क्योंकि कुछ कोडरों का उपयोग पहले से ही किया जा सकता है।

स्ट्रॉस्ट्रुप इस बारे में अपनी C ++ प्रोग्रामिंग लैंग्वेज में लिखते हैं और इससे भी ज्यादा, द डिजाइन एंड इवोल्यूशन ऑफ C ++ में लैंग्वेज के "whys" पर ज्यादा फोकस करते हैं ।

=== मूल उत्तर ===

मान लीजिए कि ऐसा नहीं हुआ।

मान लीजिए कि मैं एक पैरामीटर रहित निर्माता नहीं चाहता, क्योंकि मैं अपनी कक्षा को एक के बिना एक सार्थक स्थिति में नहीं डाल सकता। वास्तव में, यह कुछ ऐसा है structजो C # में हो सकता है (लेकिन यदि आप C # में ऑल-जीरो-एंड-नल्स का सार्थक उपयोग नहीं कर सकते हैं तो आप structगैर-सार्वजनिक रूप से दृश्यमान अनुकूलन का उपयोग कर सकते हैं, और अन्यथा एक उपयोग में डिजाइन दोष struct)।

अपने वर्ग को अपने आक्रमणकारियों से बचाने में सक्षम बनाने के लिए, मुझे एक विशेष removeDefaultConstructorखोजशब्द की आवश्यकता है । बहुत कम से कम, मुझे यह सुनिश्चित करने के लिए एक निजी पैरामीटर रहित कंस्ट्रक्टर बनाने की आवश्यकता होगी कि कोई कॉलिंग कोड डिफ़ॉल्ट न हो।

जो भाषा को कुछ और उलझा देता है। बेहतर है कि इसे न करें।

सभी में, डिफॉल्ट को हटाने के रूप में एक कंस्ट्रक्टर को जोड़ने के बारे में सोचना सबसे अच्छा है, बेहतर है कि कोई भी कंस्ट्रक्टर चीनी को एक पैरामीटर रहित कंस्ट्रक्टर को जोड़ने के लिए बिल्कुल भी कोई कंस्ट्रक्टर न होने के बारे में सोचें जो कुछ भी नहीं करता है।


1
और फिर भी, मुझे लगता है कि किसी को लगता है कि यह एक बुरा जवाब है इसे वोट करने के लिए पर्याप्त जवाब है, लेकिन मुझे या किसी और को ज्ञान देने से परेशान नहीं किया जा सकता है। जो हो सकता है, आपको पता हो, उपयोगी है।
जॉन हन्ना

मेरे जवाब पर वही वैसे मुझे यहाँ से कुछ भी गलत नहीं दिखता है।
बॉटज़ ३०००

@ Botz3000 मुझे स्कोर की परवाह नहीं है, लेकिन अगर उनकी कोई आलोचना है, तो मैं इसे पढ़ूंगा। फिर भी, इसने मुझे ऊपर से जोड़ने के लिए कुछ करने के बारे में सोचा।
जॉन हैना

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

1
@ जोगोजपन मैं विशेषज्ञ भी नहीं हूँ, लेकिन जो आदमी है - उस आदमी के रूप में, जिसने निर्णय लिया - इसके बारे में लिखा है, इसलिए मुझे होने की ज़रूरत नहीं है। संयोग से, यह एक बहुत ही दिलचस्प किताब है; कम स्तर की तकनीक पर और डिजाइन के फैसलों पर बहुत कम, एक व्यक्ति के भाषण की तरह मनोरंजक बिट्स के साथ एक नई सुविधा का प्रस्ताव करने से पहले आपको एक गुर्दा दान करना होगा (आप बहुत कठिन सोचेंगे, और केवल दो बार करेंगे) अपने भाषण से ठीक पहले दोनों टेम्पलेट और अपवादों को पेश करना।
जॉन हैना

13

यदि आप ऑब्जेक्ट निर्माण पर नियंत्रण रखने के लिए स्वयं कुछ नहीं करते हैं तो डिफ़ॉल्ट, पैरामीटर रहित कंस्ट्रक्टर को जोड़ा जाता है। एक बार जब आप नियंत्रण लेने के लिए एक एकल निर्माता बना लेते हैं, तो संकलक "बैक ऑफ" करता है और आपको पूर्ण नियंत्रण देता है।

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


आपके पास वास्तव में वह विकल्प है। पैरामीटर रहित कंस्ट्रक्टर को निजी बनाना।
mw_21

5
वही नहीं है। स्थिर तरीकों सहित कक्षा की कोई भी विधि, इसे कह सकती है। मैं इसे पूरी तरह से अप्रतिष्ठित होना पसंद करता हूँ।
एंडर्स एबेल

3

यह संकलक का एक सुविधा कार्य है। यदि आप किसी कन्स्ट्रक्टर को पैरामीटर के साथ परिभाषित करते हैं, लेकिन एक पैरामीटर रहित कंस्ट्रक्टर को परिभाषित नहीं करते हैं, तो संभावना है कि आप एक पैरामीटर्सलेस कंस्ट्रक्टर को अनुमति नहीं देना चाहते हैं।

यह कई वस्तुओं के लिए मामला है जो सिर्फ एक खाली कंस्ट्रक्टर के साथ आरंभ करने के लिए समझ में नहीं आता है।

अन्यथा आपको प्रत्येक वर्ग के लिए एक निजी पैरामीटर रहित निर्माता घोषित करना होगा जिसे आप प्रतिबंधित करना चाहते हैं।

मेरी राय में यह एक ऐसी शैली है जो एक ऐसे पैरामीटर के लिए पैरामीटरविहीन निर्माणकर्ता की अनुमति नहीं देती है जो कार्य करने के लिए मापदंडों की आवश्यकता होती है।


3

मुझे लगता है कि सवाल का दूसरा तरीका होना चाहिए: यदि आपको किसी अन्य कंस्ट्रक्टर को परिभाषित नहीं किया है, तो आपको डिफ़ॉल्ट निर्माता घोषित करने की आवश्यकता क्यों नहीं है?

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

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


1

डिफ़ॉल्ट कंस्ट्रक्टर का निर्माण केवल तभी किया जा सकता है जब क्लास में कंस्ट्रक्टर न हो। कंपाइलर को इस तरह से लिखा जाता है कि यह केवल एक बैकअप तंत्र के रूप में प्रदान करता है।

यदि आपके पास एक पैरामीटर निर्मित कंस्ट्रक्टर है, तो आप डिफ़ॉल्ट कंस्ट्रक्टर का उपयोग करके कोई ऑब्जेक्ट नहीं बनाना चाहते हैं। यदि कंपाइलर एक डिफॉल्ट कंस्ट्रक्टर प्रदान करता था, तो आपको नो-आर्ग कंस्ट्रक्टर लिखना होगा और बिना किसी तर्क का उपयोग किए वस्तुओं को रोकने के लिए इसे निजी बनाना होगा।

इसके अलावा, आपके द्वारा अक्षम निर्माण को भूल जाने, या डिफ़ॉल्ट निर्माणकर्ता का 'निजीकरण' करने की अधिक संभावना होगी, और इस तरह एक संभावित कार्यात्मक त्रुटि को पकड़ना मुश्किल होगा।

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


1

परिसर

इस व्यवहार को कक्षाओं के लिए डिफ़ॉल्ट सार्वजनिक पैरामीटर रहित निर्माता के निर्णय के एक स्वाभाविक विस्तार के रूप में देखा जा सकता है । पूछे गए प्रश्न के आधार पर हम इस निर्णय को एक आधार के रूप में लेते हैं और यह मानते हैं कि हम इस उदाहरण में इस पर सवाल नहीं उठा रहे हैं।

डिफ़ॉल्ट कंस्ट्रक्टर को हटाने के तरीके

यह इस प्रकार है कि डिफ़ॉल्ट सार्वजनिक पैरामीटर रहित कंस्ट्रक्टर को हटाने का एक तरीका होना चाहिए। इस निष्कासन को निम्नलिखित तरीकों से पूरा किया जा सकता है:

  1. एक गैर-सार्वजनिक पैरामीटर रहित निर्माता की घोषणा करें
  2. पैरामीटर के साथ एक कंस्ट्रक्टर घोषित होने पर पैरामीटर रहित निर्माता को स्वचालित रूप से हटा दें
  3. कंपाइलर को इंगित करने के लिए कुछ कीवर्ड / विशेषता पैरामीटर रहित कंस्ट्रक्टर को हटाने के लिए (अजीब पर्याप्त है कि इसे बाहर निकालना आसान है)

सर्वश्रेष्ठ समाधान का चयन

अब हम खुद से पूछते हैं: अगर कोई पैरामीटर रहित कंस्ट्रक्टर नहीं है, तो इसे किसके द्वारा प्रतिस्थापित किया जाना चाहिए? और किस प्रकार के परिदृश्यों के तहत हम डिफ़ॉल्ट सार्वजनिक पैरामीटर रहित कंस्ट्रक्टर को हटाना चाहते हैं?

चीजें जगह-जगह गिरने लगती हैं। सबसे पहले, इसे या तो एक पैरामीटर के साथ एक निर्माता के साथ प्रतिस्थापित किया जाना चाहिए, या एक गैर-सार्वजनिक निर्माता के साथ। दूसरे, वे परिदृश्य जिनके तहत आप पैरामीटर रहित निर्माणकर्ता नहीं चाहते हैं:

  1. हम यह नहीं चाहते हैं कि वर्ग बिल्कुल तैयार हो, या हम निर्माणकर्ता की दृश्यता को नियंत्रित करना चाहते हैं: एक गैर-सार्वजनिक निर्माणकर्ता घोषित करें
  2. हम मापदंडों को निर्माण पर प्रदान करने के लिए बाध्य करना चाहते हैं: मापदंडों के साथ एक कंस्ट्रक्टर घोषित करें

निष्कर्ष

हमारे पास यह है - सी #, सी ++ और जावा दो बिल्कुल सही तरीके हैं जो डिफ़ॉल्ट सार्वजनिक पैरामीटर रहित कंस्ट्रक्टर को हटाने की अनुमति देते हैं।


स्पष्ट रूप से संरचित और अनुसरण करने में आसान, +1। लेकिन ऊपर (3.) के बारे में: मुझे नहीं लगता कि निर्माण हटाने के लिए एक विशेष कीवर्ड ऐसा अजीब विचार है, और वास्तव में सी ++ 11 ने = deleteइस उद्देश्य के लिए पेश किया है।
जोगोजापान

1

मुझे लगता है कि यह संकलक द्वारा संभाला गया है। यदि आप .netअसेंबली खोलते हैं तो आपको ILDASMडिफ़ॉल्ट कंस्ट्रक्टर दिखाई देगा, भले ही वह कोड में न हो। यदि आप एक पैरामीटर निर्मित कंस्ट्रक्टर को परिभाषित करते हैं तो डिफ़ॉल्ट कंस्ट्रक्टर को मधुमक्खी नहीं दिखाई देगी।

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


0

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


0

एक वर्ग को एक निर्माणकर्ता की आवश्यकता होती है। यह अनिवार्य आवश्यकता है।

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

मैं आपको दूसरे प्रश्न का उत्तर दूंगा, हम हमेशा एक डिफ़ॉल्ट पैरामीटर रहित निर्माता क्यों चाहते हैं? ऐसे मामले हैं जहां यह वांछित नहीं है, इसलिए डेवलपर के पास इसे जोड़ने या हटाने की आवश्यकता के रूप में नियंत्रण है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.