2012-03-28 17 views
62

मुझे समझ में नहीं आ रहा है कि निम्न कोड में क्यों, जब मैं daughter टाइप करता हूं, तो डिफ़ॉल्ट grandmother() कन्स्ट्रक्टर को कॉल किया जाता है?डिफ़ॉल्ट कन्स्ट्रक्टर वर्चुअल विरासत में क्यों कहा जाता है?

मैंने सोचा कि या तो grandmother(int) कन्स्ट्रक्टर को कॉल किया जाना चाहिए (मेरे mother वर्ग कन्स्ट्रक्टर के विनिर्देश का पालन करने के लिए), या वर्चुअल विरासत के कारण यह कोड संकलित नहीं होना चाहिए।

यहां संकलक चुपचाप grandmother मेरी पीठ में डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करता है, जबकि मैंने कभी इसके लिए नहीं पूछा।

#include <iostream> 

class grandmother { 
public: 
    grandmother() { 
     std::cout << "grandmother (default)" << std::endl; 
    } 
    grandmother(int attr) { 
     std::cout << "grandmother: " << attr << std::endl; 
    } 
}; 

class mother: virtual public grandmother { 
public: 
    mother(int attr) : grandmother(attr) { 
     std::cout << "mother: " << attr << std::endl; 
    } 
}; 

class daughter: virtual public mother { 
public: 
    daughter(int attr) : mother(attr) { 
     std::cout << "daughter: " << attr << std::endl; 
    } 
}; 

int main() { 
    daughter x(0); 
} 
+0

क्या कंपाइलर (और संस्करण)? आपने किस तर्क के साथ संकलन किया? – orlp

+0

जीसीसी 4.6.3 20120306 (रेड हैट 4.6.3-2) फेडोरा 15 पर। तर्क हैं: -O0 -g3 -Wall -c -fmessage-length = 0 –

+0

g ++ 4.1.2 में एक ही समस्या है: http: // codepad.org/L0jBXfSP – orlp

उत्तर

66

आभासी विरासत का उपयोग करते समय, आभासी आधार वर्ग के निर्माता सीधे सबसे व्युत्पन्न वर्ग के निर्माता द्वारा कहा जाता है। इस मामले में, daughter कन्स्ट्रक्टर सीधे grandmother कन्स्ट्रक्टर को कॉल करता है।

चूंकि आपने प्रारंभिक सूची में grandmother कन्स्ट्रक्टर को स्पष्ट रूप से कॉल नहीं किया है, तो डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल किया जाएगा। सही कन्स्ट्रक्टर को कॉल करने के लिए, इसे

daugther(int attr) : grandmother(attr), mother(attr) { ... } 

This FAQ entry भी देखें।

+2

वह पूरी तरह से समझ में आता है, धन्यवाद! पदानुक्रम में सभी रचनाकारों को अंतिम कक्षा से बुलाया जाता है, न कि उनके संबंधित बाल वर्ग द्वारा। उस बारे में कभी सोचा नहीं। सी ++ spec कभी कभी मुश्किल हो सकता है ... –

+0

धन्यवाद! तो आभासी विरासत के मामले में, सबसे अच्छा करना श्रृंखला के सभी रचनाकारों को मैन्युअल रूप से कॉल करना है। –

+0

उत्कृष्ट जवाब! धन्यवाद! –

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