2009-06-23 8 views
7

this question में फैक्टरी विधि बनाना जब संकलक नया का समर्थन नहीं करता है और प्लेसमेंट नया पर चर्चा की जाती है। स्पष्ट रूप से मॉलोक() का उपयोग करके कुछ उपयुक्त समाधान तैयार किए जा सकते हैं यदि नियुक्ति द्वारा किए गए सभी आवश्यक कदम कुछ किसी भी तरीके से पुन: उत्पन्न किए जाते हैं।सी ++ में प्लेसमेंट द्वारा किए गए कार्यों की पूरी सूची क्या है?

प्लेसमेंट नया क्या करता है - मैं सूचीबद्ध करने की कोशिश करूंगा और आशा करता हूं कि कुछ भी याद न करें - निम्नलिखित को छोड़कर?

सभी सदस्य चर
  • vtable सूचक अनुसार सेट के लिए सभी आधार वर्ग रिकर्सिवली
  • कॉल निर्माणकर्ता और initializers (यदि हो तो) के लिए
    • कॉल कंस्ट्रक्टर्स।

    अन्य गतिविधियां क्या हैं?

  • उत्तर

    6

    प्लेसमेंट new सब कुछ नियमित new करता है, स्मृति आवंटित किए बिना करता है।

    मुझे लगता है कि आप अनिवार्य रूप से किसी न किसी है कुछ मामूली स्पष्टीकरण के साथ, क्या होता है:

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

    निर्माण/आरंभीकरण का क्रम इस प्रकार है: घोषणा के क्रम में घोषणा के क्रम में

    1. आभासी आधार वर्ग
    2. nonvirtual आधार वर्ग घोषणा आदेश
    3. वर्ग निर्माता में
    4. वर्ग के सदस्यों खुद
    +0

    +1 वर्चुअल बेस क्लास निर्माण को समझने के लिए –

    4

    सेट vtable सूचक के अनुसार

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

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

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

    0

    @laalto उत्तर सामान्य रूप से सच है। हालांकि, एक अपवाद नियम साबित करता है।

    vtable पॉइंटर्स को कन्स्ट्रक्टर कॉल के हिस्से के रूप में प्रारंभ किया गया है, अलग से नहीं।

    माइक्रोसॉफ्ट C++ कम्पाइलर तथाकथित स्थानीय vftables जानता है, अर्थात vftables एक DLL करने के लिए स्थानीय हैं और हर वर्ग के लिए आयातित क्लोन कर दिया जाएगा। ऐसा इसलिए है क्योंकि संकलक एक संशोधित विनाशक प्रदान करना चाहता है जो मूल एक (एसए here) लपेटता है।

    जब भी आप एक आयातित वर्ग का ऑब्जेक्ट बनाते हैं तो संकलक कोड उत्पन्न करता है जो मूल vftable सूचक (0) को कन्स्ट्रक्टर आमंत्रण के बाद स्थानीय सूचक (ओं) के साथ ओवरराइट करता है। यह कोड प्लेसमेंट नई कॉल में भी मौजूद है।

    उपरोक्त पद में उल्लिखित लोगों के अलावा एक और कामकाज मौजूद है। यह कामकाज आपको मूल शीर्षलेख फ़ाइलों को बदलने के लिए मजबूर नहीं करता है। कृपया यहां एक नज़र डालें: https://godbolt.org/g/YQsffY

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