2008-12-07 17 views
148

क्यों इस कोड: इन त्रुटियों मेंविरासत कंस्ट्रक्टर्स

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
}; 

int main(void) 
{ 
    B *b = new B(5); 
    delete b; 
} 

परिणाम:

 
main.cpp: In function ‘int main()’: 
main.cpp:13: error: no matching function for call to ‘B::B(int)’ 
main.cpp:8: note: candidates are: B::B() 
main.cpp:8: note:     B::B(const B&) 

एक के निर्माता के वारिस बी नहीं करना चाहिए?

(यह उपयोग कर रहा है जीसीसी)

उत्तर

248

सी ++ में 03 मानक कन्स्ट्रक्टर विरासत में नहीं मिल सकते हैं और आपको स्वयं को मूल कार्यान्वयन को कॉल करके मैन्युअल रूप से एक-एक करके प्राप्त करने की आवश्यकता है। यदि आपका कंपाइलर सी ++ 11 मानक का समर्थन करता है, तो एक कन्स्ट्रक्टर विरासत है। अधिक देखने के लिए Wikipedia C++11 article देखें। नए मानक के साथ आप लिखें:

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
    using A::A; 
}; 
+9

इसका कारण यह है एक साल है कि कोई संकलक है कि वास्तव में इसके बाद के संस्करण कोड का निर्माण कर सकते :-) – Mikhail

+11

@Mikhail किया गया है से अधिक के लिए काफी बुराई है: दोनों बजना और जी ++ अब कंस्ट्रक्टर्स इनहेरिट समर्थन करना चाहिए: http: // बजना .llvm.org/cxx_status.html http://gcc.gnu.org/projects/cxx0x.html सही उत्तर के रूप में इसे ऊपर उठाने की अनुशंसा करें। –

+0

बस पूछ रहा है, क्या एक विरासत वाला निर्माता बेस क्लास के निजी सदस्यों तक पहुंच/प्रारंभ करने में सक्षम होगा? या मुझे उन्हें संरक्षित के रूप में निर्दिष्ट करना होगा? – Markasoftware

4

आप स्पष्ट रूप से बी में निर्माता को परिभाषित करने और स्पष्ट रूप से माता पिता के लिए निर्माता फोन है।

B(int x) : A(x) { } 

या

B() : A(5) { } 
80

कंस्ट्रक्टर्स नहीं ली गई है। उन्हें बाल कन्स्ट्रक्टर द्वारा स्पष्ट रूप से या स्पष्ट रूप से बुलाया जाता है।

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

class A 
{ 
public: 
    explicit A(int x) {} 
}; 

class B: public A 
{ 
public: 
    explicit B(int x) : A(x) { } 
}; 

अद्यतन: सी ++ 11 में, कंस्ट्रक्टर्स विरासत में मिला जा सकता है। विवरण के लिए सुमा का जवाब देखें।

1

सही कोड है

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
     public: 

    B(int a):A(a){ 
      } 
}; 

main() 
{ 
    B *b = new B(5); 
    delete b; 
} 

त्रुटि b/c कक्षा बी नहीं पैरामीटर निर्माता है और दूसरा यह आधार वर्ग प्रारंभकर्ता बेस कक्षा के निर्माता कॉल करने के लिए होना चाहिए

आप चाहें, तो आप अभी भी अपने आप को पैर में मैं द्वारा गोली मार कर सकते हैं: पैरामीटर निर्माता

3

यह Bjarne Stroustrup's page से सीधे है एक व्युत्पन्न वर्ग जिसमें आप नए सदस्य चर प्रारंभ की आवश्यकता होगी, को परिभाषित में कंस्ट्रक्टर्स nheriting:

struct B1 { 
    B1(int) { } 
}; 

struct D1 : B1 { 
    using B1::B1; // implicitly declares D1(int) 
    int x; 
}; 

void test() 
{ 
    D1 d(6); // Oops: d.x is not initialized 
    D1 e;  // error: D1 has no default constructor 
} 
+0

'int x = 77;' int x के बजाय; 'समस्या को हल करेगा –

+0

@ BЈовић: टेम्पलेट बी (args && ... args) :: एक (एसटीडी हां, यह Bjarne के पृष्ठ पर अगले वाक्य :) –

1

कैसे सब कंस्ट्रक्टर्स बाध्य करने के लिए एक टेम्पलेट समारोह का उपयोग कर के बारे में?

template <class... T> Derived(T... t) : Base(t...) {} 
+2

शायद आप सही अग्रेषण के साथ यह करना चाहिए :: आगे < Args > (तर्क) ...) {} –

+0

और आपने अभी 'व्युत्पन्न' की प्रतिलिपि निर्माता को तोड़ दिया। – Barry

+0

क्या बेस के कन्स्ट्रक्टर को भी टेम्पलेट करना होगा? जब आप बेस (टी ...) कहते हैं, तो बेस को जो भी टी है, उसके लिए टेम्पलेट करना होगा? – Zebrafish

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