2011-12-28 13 views
16

सी ++ मानक कहता है कि एक निर्माता या विनाशक से शुद्ध वर्चुअल फ़ंक्शन का आविष्कार प्रतिबंधित है। इसका कारण क्या है? मानक जगह इस तरह एक प्रतिबंध क्यों होना चाहिए?कन्स्ट्रक्टर और विनाशक से शुद्ध आभासी आमंत्रण

+5

यह वर्जित नहीं है। यह अपरिभाषित कहता है। कारण कंपेलरों को सबसे अधिक लचीलापन संभव है। –

+1

कृपया उद्धरण लिखने के लिए "नाटक" उद्धरणों का उपयोग न करें जो अस्तित्व में नहीं है। –

उत्तर

19

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

रचनाकारों में आभासी तरीकों को कॉल करने के आसपास एक समान प्रतिबंध मौजूद है। आप उप-वर्ग के लिए वर्चुअल विधि को कॉल नहीं कर सकते जिसका कन्स्ट्रक्टर अभी तक नहीं चला है।

+0

यहां आप 'वर्चुअल फ़ंक्शन 'के बारे में बात करते हैं' शुद्ध वर्चुअल फ़ंक्शंस ' –

+3

वर्चुअल फ़ंक्शंस के बारे में मेरी टिप्पणियां शुद्ध वर्चुअल फ़ंक्शंस पर भी लागू होती हैं। –

+0

लेकिन शुद्ध वर्चुअल फ़ंक्शन अधिक छोटा है: इसे कक्षा में सभी (कन्स्ट्रक्टर, विनाशक या अन्य विधि) में नहीं कहा जा सकता है। –

5

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

+0

और यह एक गैर शुद्ध वर्चुअल फ़ंक्शन से अलग है ... कैसे? –

0

फ़ंक्शन केवल उप-वर्गों में लागू होने वाला प्रोटोटाइप है, यह वास्तव में कक्षा में मौजूद नहीं है ... इसलिए इसे कन्स्ट्रक्टर या विनाशक में नहीं कहा जा सकता है)।

समारोह का कोई कार्यान्वयन है तो, बस, वहाँ फोन करने के लिए :)

उपवर्गों कि शुद्ध मौजूद नहीं है जब निर्माता/नाशक बुला आभासी implementsthe कोई कोड है।

2

याद रखें कि एक निर्माता/नाशक से एक "गैर-शुद्ध" आभासी समारोह लागू तथ्य यह है कि समारोह आभासी है, और हमेशा अपनी कक्षा में कार्यान्वयन कॉल पर ध्यान नहीं देता, में व्युत्पन्न वर्ग निर्माण किया जा रहा नहीं। यही कारण है कि आप कन्स्ट्रक्टर या विनाशक से शुद्ध आभासी नहीं कह सकते हैं: जहां तक ​​वे चिंतित हैं, आपके शुद्ध वर्चुअल फ़ंक्शन में कोई कार्यान्वयन नहीं है।

4

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

एक बेशक वर्ष मसौदा सी ++ स्टैंडर्ड से

, लेकिन प्रासंगिक अंतरों मैं आकर्षित करेंगे प्रासंगिक बने हुए:

10.4-6 सदस्य कार्यों एक निर्माता (या नाशक) से कहा जा सकता है एक सार का कक्षा; ऐसे कन्स्ट्रक्टर (या विनाशक) से बनाई गई वस्तु (या नष्ट) के लिए प्रत्यक्ष या अप्रत्यक्ष रूप से शुद्ध वर्चुअल फ़ंक्शन पर वर्चुअल कॉल (class.virtual) बनाने का प्रभाव अनिर्धारित है।

यह पूर्व-अर्धविराम वाक्यांश के सन्दर्भ में पोस्ट के लिए प्रासंगिक रूप से प्रासंगिक है, जैसा कि आप जोर दे रहे हैं, यह सब कुछ अलग है। अलग ढंग से व्यक्त:

undefined behaviour happens when an abstract class's constructor or destructor calls one of its own member functions that is (still) pure virtual. 

मैं क्वालीफायर में शामिल हैं "(अब भी)" के रूप में शुद्ध आभासी कार्यों परिभाषाओं दिया जाता है - और "शुद्ध" नहीं रह - एक वर्ग पदानुक्रम में कुछ बिंदु पर। यह थोड़ा अजीब है, लेकिन मानक के इस हिस्से पर विचार करें:

यदि कक्षा कम से कम एक शुद्ध वर्चुअल फ़ंक्शन है तो एक वर्ग सार है।[नोट: ऐसा फ़ंक्शन विरासत में प्राप्त हो सकता है: नीचे देखें। ]

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

परिणाम: यदि कार्य - पदानुक्रम में कॉलिंग कन्स्ट्रक्टर/विनाशक के स्तर के परिप्रेक्ष्य से - पहले ही परिभाषित किया गया है, इसे अच्छी तरह से परिभाषित व्यवहार के साथ बुलाया जा सकता है।

मानक में अपरिभाषित की इस समझ के साथ, हम आपके प्रश्नों पर वापस आ सकते हैं: "इसका कारण क्या है? मानक को इस तरह प्रतिबंध क्यों देना चाहिए?"

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

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

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

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