2012-03-17 27 views
8

यह एक बहुत ही बुनियादी सवाल है, मैंने इसे खोजा लेकिन मैं सिर्फ इस समुदाय से पूछना चाहता हूं कि हमारे पास constructors और methods दोनों हैं। लेकिन आम तौर पर हम विधियों के बजाय चर को प्रारंभ करने के लिए कन्स्ट्रक्टर का उपयोग करते हैं। मुझे लगता है कि दोनों चर को प्रारंभ करने के लिए इस्तेमाल किया जा सकता है। तो दोनों के बीच बुनियादी अंतर क्या है। क्या कोई ठोस कारण है? यह एक बहुत ही बुनियादी सवाल है इसलिए इसे शुरुआती स्तर के लिए सहन करें। अग्रिम धन्यवाद ..कार्यों के बजाय कन्स्ट्रक्टर का उपयोग क्यों किया जाता है?

उत्तर

6

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

उदाहरण के लिए, इन सभी एक वस्तु instantiating निर्माता

Foo* p = new Foo(); 
Foo p; 

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

class Foo 
{ 
private: 
    Foo(); 
public: 
    Foo(int param1, double param2) 
}; 

इससे पहले कक्षा को तुरंत चालू करने से पहले तर्कों की आवश्यकता का लाभ होता है। तो तुम क्या करने के लिए मजबूर कर रहे हैं:

Foo* p = new Foo(1, 5.0); 

और वैध तर्क के साथ निर्माण करने में नाकाम रहने के लिए एक संकलक त्रुटि हो जाता है:

Foo* p = new Foo(); // compiler error 

तो जब भी संभव हो, हमेशा एक निर्माता में अपने प्रारंभ कर की ओर गलती । ऐसे कुछ मामले हैं जहां एक कन्स्ट्रक्टर व्यवहार्य नहीं हो सकता है। उदाहरण के लिए, एक कन्स्ट्रक्टर को विफल करने का एकमात्र तरीका अपवाद का उपयोग कर है। निर्माण करने में विफलता "नियमित" हो सकती है और वास्तव में असाधारण नहीं हो सकती है। कुछ आर्किटेक्चर पर अपवाद भी महंगा हो सकता है। एक और मामला तब हो सकता है जब आप यह सुनिश्चित करना चाहते हैं कि वर्चुअल विधियां पूरी तरह से बंधी हों, जो केवल निर्माण के बाद ही सत्य होने की गारंटी है।

+0

वास्तव में मैं उपयोगकर्ता द्वारा मांगे गए कुछ मूल्यों के साथ प्रारंभिकता पूछ रहा हूं, मान लीजिए कि सिमुलेशन उद्देश्य के लिए हमें दिए गए मानों के बारे में 20 चर प्रारंभ करना होगा। यदि मैं प्रत्येक चर को सही ढंग से प्रारंभ करता हूं तो इस मामले में आप अपने तर्क से चिपके रहेंगे? –

+0

@kashmirilegion मेरे संपादन देखें। यदि आपको 20 चर शुरू करने की आवश्यकता है तो आप या तो एक कन्स्ट्रक्टर को परिभाषित कर सकते हैं जो 20 चर या एक स्ट्रक्चर लेता है। –

+0

को मिला। बहुत बहुत धन्यवाद –

3

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

निम्नलिखित पर विचार करें:

class Foo { 
public: 
    // Constructor 
    Foo() : x(53) // Initialise x 
    {} 

    void bar() { 
     x = 42;  // Error, attempt to *assign* a const member! 
    } 

private: 
    const int x; 
}; 

निर्माता के बिना, सदस्य x आरंभ करने के लिए कोई रास्ता नहीं होगा।

+0

जो तब तक अच्छा और अच्छा है जब तक आपको रनटाइम पर त्रुटि कोड वापस करने की आवश्यकता न हो। : पी – chrisaycock

+0

@ क्रिससाकॉक: टच। लेकिन आपके अच्छे उत्तर के लिए हमेशा अपवाद हैं ... –

+0

+1। धन्यवाद, आपके तर्क ने रचनाकारों के बारे में स्पष्ट तरीका बनाने के लिए दिमाग में मजबूती दी। –

0

जब आप किसी फ़ंक्शन के विपरीत ऑब्जेक्ट बनाते हैं तो कन्स्ट्रक्टर स्वचालित रूप से लागू होता है। साथ ही, कन्स्ट्रक्टर का उपयोग को इंगित करता है कि यह वस्तु के प्रारंभ के लिए है।

0

कल्पना कीजिए कि आपके पास एक सदस्य चर है जिसमें कोई खाली कन्स्ट्रक्टर नहीं है। फिर आपके पास अपने कन्स्ट्रक्टर की प्रारंभकर्ता सूची में इसे आरंभ करने के अलावा कोई दूसरा विकल्प नहीं है।

इसके अलावा जब आप नए ऑपरेटर के साथ एक सरणी आवंटित करते हैं तो कन्स्ट्रक्टर को कॉल किया जाता है, जबकि विधियों के साथ प्रारंभिक कोड कोड को और अधिक जटिल बना देगा।

सामान्य रूप से कन्स्ट्रक्टर में जटिल तर्क होना बहुत अच्छा विचार नहीं है, लेकिन सरल प्रारंभिकता वहां की जानी चाहिए (यह सुनिश्चित करने के लिए कि आपको अपनी वस्तु कुछ मान्य स्थिति में है)।

1

रचनाकारों को स्वचालित रूप से कॉल किया जाता है, इसलिए चिंता करने की कोई आवश्यकता नहीं है कि उपयोगकर्ता ने अभी तक प्रारंभिक विधि का आह्वान किया है या नहीं। हालांकि, Google style guide does have something to say about constructors:

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

Google की सिफारिश एक कन्स्ट्रक्टर में सीधी शुरुआत, और एक अलग विधि में गैर-मामूली दीक्षा होना है।

+0

जो सब ठीक और अच्छा है, जब तक कि आप अपरिवर्तनीय वस्तुओं के प्रशंसक न हों। –

+0

Google की C++ शैली मार्गदर्शिका का पालन करने के लिए मुख्य तर्क बड़ा नाम प्रतीत होता है।मैं अपवादों का उपयोग करके (नहीं) पर उनके विचार को पूरी तरह से नापसंद करता हूं। यदि आप अपवादों का उपयोग नहीं करते हैं, तो आप सी ++ की एक बहुत सी सी जैसी शैली का उपयोग कर रहे हैं। एक प्रसिद्ध सी ++ विशेषज्ञ ने एक बार कहा: http://www2.research.att.com/~bs/3rd_safe0.html अपनी बुलेट सूची का उत्तर देने के लिए: (1) तो बस अपवादों का उपयोग करें (आपको अभी पता चला है कि वहां कन्स्ट्रक्टर/आरएआईआई का उपयोग करने के लिए आवश्यक) (2) दोबारा, यदि आप अपवाद फेंकते हैं तो आपके पास अमान्य ऑब्जेक्ट नहीं होगा (3) मैं मानता हूं, कुछ ग़लत समस्याएं उत्पन्न हो सकती हैं, संकलक आपको चेतावनी देना चाहिए। (4) तो, रचनाकारों में कोई कोड नहीं है? – Andre

0

चर शुरू करने में कोई संदेह नहीं है, एक बहुत ही महत्वपूर्ण प्रोग्रामिंग अभ्यास। कक्षाओं का उपयोग करते समय, विकल्प उन्हें विधियों के अंदर शुरू करना है। इस प्रकार, हम दो कदम है: -

  1. परिभाषित विधि
  2. कॉल प्रारंभ प्रदर्शन करने के लिए विधि

लेकिन अगर 'विधि के बुला' भुला दिया जाता है, चर अंत कबाड़ मूल्यों होने । प्रोग्रामर के लिए जीवन को आसान बनाने के लिए, एक निर्माता विधि की अवधारणा में लाया गया था

कंस्ट्रक्टर्स के साथ, हम बस एक कदम है: -।

  1. निर्माता

'बुला हिस्सा' है को परिभाषित करें जब भी कक्षा का एक नया ऑब्जेक्ट बनाया जाता है तो स्वचालित रूप से प्रदर्शन किया जाता है।

0

कन्स्ट्रक्टर्स का उपयोग कुशल स्मृति प्रबंधन के लिए किया जा सकता है, जो कार्यों के साथ संभव नहीं है।

विनाशक का उपयोग करने पर रचनाकारों को नष्ट करने के लिए उपयोग किया जा सकता है।

इसके अलावा, कॉपी कन्स्ट्रक्टर का उपयोग स्मृति गलत घटनाओं के कारण कठिनाइयों या त्रुटियों को रोकने के लिए जाना जाता है।

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

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