2011-02-02 17 views
17

में एक विधि को कॉल करना हर्ब सटर अपने http://www.gotw.ca लेखों में से एक में उल्लेख करता है कि एक ऑब्जेक्ट बनाया गया है (वैध अस्तित्व है) केवल अगर कन्स्ट्रक्टर निष्पादित करता है तो इसे एक कच्चे तरीके से नियंत्रित करने के लिए इसे अपने अंतिम ब्रेस से परे पास करता है।कन्स्ट्रक्टर

अब कोड निम्नलिखित

class A 
{ 
    public: 
    A() 
    { 
     f(); 
    } 

    void f() 
    { 
     cout << "hello, world"; 
    } 

}; 

int main() 
{ 
    A a; 
} 

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

अभी भी निर्माता के अंदर वास्तव में एक वैध "यह" है और f() कहा जाता है।

मुझे नहीं लगता कि हर्ब कुछ गलत कह रहा है ... लेकिन अनुमान है कि मैं इसे गलत तरीके से व्याख्या कर रहा हूं .... क्या कुछ मुझे बता सकते हैं कि वास्तव में क्या है?

यहां लेख का लिंक है: http://www.gotw.ca/gotw/066.htm यह रचनाकारों के अपवादों के बारे में बात करता है। विशेष रूप से यहां से निकाला गया है जिस पर मेरा प्रश्न आधारित है:

- जब कोई ऑब्जेक्ट का जीवनकाल शुरू होता है? जब इसका कन्स्ट्रक्टर सफलतापूर्वक पूरा हो जाता है और सामान्य रूप से लौटाता है। यही है, नियंत्रण कन्स्ट्रक्टर बॉडी या पहले के रिटर्न स्टेटमेंट के अंत तक पहुंचता है।

- जब किसी ऑब्जेक्ट का जीवनकाल समाप्त होता है? जब इसके विनाशक शुरू होता है। यही है, नियंत्रण विनाशक शरीर की शुरुआत तक पहुंचता है। यहां महत्वपूर्ण बिंदु यह है कि वस्तु का राज्य अपने जीवनकाल से पहले ठीक उसी तरह होता है जैसा कि उसके जीवनकाल के समाप्त होने के बाद होता है - कोई वस्तु नहीं होती है, अवधि होती है।

हम सी ++ निर्माता मॉडल के रूप में निम्नानुसार संक्षेप में प्रस्तुत कर सकते हैं:

Either: 

(a) The constructor returns normally by reaching its end or a return statement, and the object exists. 

Or: 

(b) The constructor exits by emitting an exception, and the object not only does not now exist, but never existed. 

उत्तर

15
क्या हर्ब कहते से

अब, हम यह नहीं कह सकते कि एक के बाद से पूरी तरह से नहीं है इस अवलोकन कुंजी सवाल करने के लिए हमें लाता है कन्स्ट्रक्टर के अंदर कॉलिंग एफ() के अंदर निर्मित अमान्य है क्योंकि "यह" पीआरटी तैयार नहीं है।

है कि केवल जब f()class A या उसके वंशानुगत पदानुक्रम के virtual तरीका है और आप सही वस्तु के अनुसार f() के लिए क्रम संकल्प की उम्मीद है। सरल शब्दों में, virtual अगर कन्स्ट्रक्टर के अंदर विधि लागू की जाती है तो तंत्र किक नहीं करता है।

यदि f() वर्चुअल फ़ंक्शन नहीं है, तो इसे कन्स्ट्रक्टर से कॉल करने में कोई हानि नहीं है बशर्ते आपको पता चले कि वास्तव में f() क्या करता है। प्रोग्रामर आमतौर पर कन्स्ट्रक्टर से initialize() जैसे वर्ग विधियों को कॉल करते हैं।

क्या आप मुझे हर्ब सटर के आलेख का लिंक दे सकते हैं?

+7

है "ऐसा लगता है कि आप ध्यान से पढ़ें नहीं किया हर्ब Sutter लेख।" - थोड़ा कठोर विचार है कि आप अभी तक लेख पर अपना हाथ नहीं डाल सकते ... – razlebe

+0

@sgreeve: कठोर? क्यूं कर? – Nawaz

+3

आप मान रहे हैं कि ओपी ने लेख को ध्यान से नहीं पढ़ा है। लेख को देखे बिना, आप नहीं जानते कि क्या यह स्थिति अच्छी तरह से समझाया गया है, अगर बिलकुल भी। – razlebe

8

जब तक कार्यक्रम प्रवाह आपके कन्स्ट्रक्टर में प्रवेश करता है, तब तक ऑब्जेक्ट की मेमोरी आवंटित की जाती है और this पॉइंटर वास्तव में मान्य है।

क्या हर्ब का अर्थ है, यह है कि ऑब्जेक्ट का राज्य पूरी तरह से प्रारंभ नहीं हो सकता है। विशेष रूप से, यदि आप A से प्राप्त कक्षा का निर्माण कर रहे हैं, तो उस कक्षा के निर्माता को तब भी नहीं कहा जाएगा जब आप ए के कन्स्ट्रक्टर के अंदर हों।

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

0

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

2

जीवन भर से निहितार्थ अभी तक शुरू नहीं हुआ है, मुख्य रूप से यह है कि, निर्माता को अपवाद फेंकना चाहिए, विनाशक नहीं चलाया जाएगा।

2

नोट: यह सही लेख के साथ आसान हो गया होता है, ताकि हम कुछ संदर्भ

लाइफटाइम विचार वास्तव में बहुत जटिल हैं हो सकता था।

एक वस्तु के निर्माता को देखते हुए, वहाँ विचारों के दो अलग-अलग बात कर रहे हैं:

  • बाहरी: एक वस्तु के उपयोगकर्ता यानी
  • आंतरिक: यानी, आप जब निर्माणकर्ता और विनाशकर्ता (विशेष रूप से)
  • लेखन
देखने के बाहरी बिंदु से

, एक वस्तु के जीवनकाल:

  • एक बार निर्माता सफलतापूर्वक पूरा कर लिया
  • समाप्त होता है जब नाशक

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

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

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