2009-10-28 16 views
11

मैं एक वर्ग MyBase कहा जाता है जो एक निर्माता और नाशक है है:क्या बेस क्लास के कन्स्ट्रक्टर और विनाशक को व्युत्पन्न लोगों के साथ बुलाया जाता है?

class MyBase 
{ 
public: 
    MyBase(void); 
    ~MyBase(void); 
}; 

और मैं एक वर्ग, केले कहा जाता है कि इतने तरह MyBase फैली है:

class Banana:public MyBase 
{ 
public: 
    Banana(void); 
    ~Banana(void); 
}; 

नए निर्माता के कार्यान्वयन करता है और केला में विनाशक माईबेस को ओवरराइड करता है, या फिर भी वे मौजूद हैं, और केला कन्स्ट्रक्टर/विनाशक के पहले या बाद में कहने के लिए कहा जाता है?

धन्यवाद, और मेरी माफी माँगती है अगर मेरा प्रश्न मूर्खतापूर्ण लगता है।

बदलें

class Banana:MyBase 

करने के लिए::

+9

दो सबसे अच्छा सरल सी ++ प्रश्नों के उत्तर प्राप्त करने के तरीके: 1) एक साधारण परीक्षण का मामला (लिखने निर्माणकर्ता और विनाशकर्ता में जैसे डाल COUTS), और 2) देखें कि क्या यह http पर जवाब है: // www। parashift.com/c++-faq-lite/ – Artelius

+0

यह आम तौर पर आप जो पूछ रहे हैं उससे संबंधित प्रश्न को प्रासंगिक बनाने में मदद करता है, ताकि आप यह देखने के लिए कि आप वास्तव में क्या पूछ रहे हैं, विवरण को देखने के बजाय। –

+0

यह कोड कई कारणों से संकलित नहीं होगा। अर्थात। एक वर्ग केले में विनाशक नहीं हो सकता "~ माइबेस()"। पोस्ट करने से पहले कृपया अपना कोड सत्यापित करें। –

उत्तर

6

यह कहना चाहिए

class Banana : public MyBase 
{ 
public: 
    Banana(void); 
    ~Banana(void); 
}; 

व्युत्पन्न वर्ग के निर्माता कहा जाता हो जाता है बेस क्लास के निर्माता के बाद। विनाशकों को उलट क्रम में बुलाया जाता है।

2

आप विरासत के प्रकार याद कर रहे हैं

के रूप में के लिए
class Banana: public MyBase 

नई निर्माता के कार्यान्वयन करता है और घ केले में निर्माता ने माइबेज को ओवरराइड किया है, या वे अभी भी मौजूद हैं, और से पहले या केले कन्स्ट्रक्टर/ विनाशक निष्पादन के बाद कहें?

उत्तराधिकारी निष्पादन का क्रम नीचे से ऊपर तक, इसका मतलब है कि माइबेस को पहले कहा जाएगा, फिर केले। यदि आपके पास एक और सबक्लास था, तो इसे अंतिम कहा जाएगा।

इस उदाहरण लें:

class RottenBanana : public Banana 

विरासत श्रृंखला अब RottenBanana है -> केले -> MyBase

इस वर्ग के कंस्ट्रक्टर्स केले MyBase पर शुरू और फिर, तो RottenBanana बुला बुलाया जाएगा।

+2

विरासत का प्रकार वैकल्पिक है, जब आप इसे नहीं बताते हैं, तो यह कक्षाओं के लिए 'निजी' विरासत और structs के लिए 'सार्वजनिक' होगा (सभी सदस्यों के लिए केवल वही डिफ़ॉल्ट पहुंच स्तर)। साथ ही, कन्स्ट्रक्टर कॉल चेन के साथ उत्तर थोड़ा कमजोर है: सबसे व्युत्पन्न ऑब्जेक्ट की प्रारंभिक सूची पहली चीज है जो निष्पादन शुरू करती है, जो उसके मूल कन्स्ट्रक्टर को एक निहित या स्पष्ट कॉल के साथ श्रृंखला बनाएगी, उस निर्माता की प्रारंभिक सूची शुरू होगा और इसी तरह ... पूरा करने वाला पहला कन्स्ट्रक्टर माइबबेस कन्स्ट्रक्टर होगा जैसा कि आप बताते हैं, फिर पदानुक्रम –

14

एक बेस कन्स्ट्रक्टर हमेशा व्युत्पन्न कन्स्ट्रक्टर से पहले बुलाया जाएगा। आधार विनाशक को संरक्षित विनाशक के बाद बुलाया जाएगा।

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

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

उपर्युक्त होता है क्योंकि एक बार जब आप एक कन्स्ट्रक्टर घोषित करते हैं तो कोई डिफ़ॉल्ट कन्स्ट्रक्टर उत्पन्न नहीं होता है।

7

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

सही ढंग से व्युत्पन्न वर्ग को साफ करने में सक्षम हो के लिए, आपको virtual के रूप में आधार वर्ग नाशक घोषित करना चाहिए:

virtual ~MyBase() { ... } 
+3

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

+0

@ ड्रिबीस: सच। भ्रम को रोकने के लिए संपादित किया गया। बेशक, यह तकनीकी रूप से वर्चुअल विधि को ओवरराइड कर रहा है। हालांकि, बेस क्लास कन्स्ट्रक्टर को कॉल की तरह ही जरूरी है और संकलक द्वारा स्वचालित रूप से डाला जाता है यदि कोई स्पष्ट रूप से नहीं बताया गया है, तो आधार विनाशक कॉल ओवरराइड विनाशक में डाला जाएगा; व्युत्पन्न कार्यान्वयन समाप्त होने के बाद प्रभावी रूप से बेस विनाशक को बुलाया जाता है। –

3

निर्माणकर्ताओं को विरासत के पेड़ में शीर्ष स्थान कहा जाता है। ऐसा इसलिए है कि व्युत्पन्न कन्स्ट्रक्टर बेस ऑब्जेक्ट को आधार के किसी भी गुण का उपयोग करने से पहले पूरी तरह से आरंभ होने पर आधारित हो सकता है।

विनाशकों को कन्स्ट्रक्टर के रिवर्स ऑर्डर में बुलाया जाता है, इसी कारण से - व्युत्पन्न कक्षा आधार पर निर्भर करती है, लेकिन आधार व्युत्पन्न पर निर्भर नहीं होता है।

यदि वहाँ एक आधार वर्ग के लिए सूचक के माध्यम से वस्तु को नष्ट करने के किसी भी संभावना है, तो आप विनाशकर्ता virtual के सभी घोषित करना चाहिए।

4

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

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

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

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

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

Destructors आभासी

विनाश वर्णन ऊपर सबसे व्युत्पन्न नाशक करने के लिए कॉल के साथ शुरू होता होना चाहिए।या वस्तु delete एक आधार वर्ग जिसका नाशक आभासी है के माध्यम से घ है जब यह सबसे व्युत्पन्न प्रकार, के लिए सूचक पर delete फोन करके प्राप्त किया जा सकता है जब एक ऑटो वस्तु क्षेत्र से बाहर चला जाता है।

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

-2

यदि आप एक ईईजीएमोडआरजीबी ऑब्जेक्ट को चालू करते हैं (जिसमें त्रि रंग का नेतृत्व होता है) - तो उसे तुरंत हटा दें, आप ब्लू, ग्रीन, पीला, और लाल रंगों को एक-दूसरे के लिए प्रत्येक क्रम में देखेंगे।

class EEGMode { 
public: 

    EEGMode() { setAllPixelsToColor(BLUE); delay(1000); } 
    virtual ~EEGMode() { setAllPixelsToColor(RED); delay(1000); } 

}; 


class EEGModeRGB : public EEGMode { 
public: 

    EEGModeRGB() { setAllPixelsToColor(GREEN); delay(1000); } 
    virtual ~EEGModeRGB() { setAllPixelsToColor(YELLOW); delay(1000); } 

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