2012-02-07 17 views
31

एक वर्ग पदानुक्रम पर विचार करें जहां A बेस क्लास है और BA से निकला है।निहित प्रति कन्स्ट्रक्टर बेस क्लास कॉपी कन्स्ट्रक्टर को क्यों कॉल करता है और परिभाषित प्रति कन्स्ट्रक्टर नहीं करता है?

प्रतिलिपि निर्माता B में परिभाषित नहीं किया गया है, संकलक एक संश्लेषण जाएगा। जब बुलाया जाता है, तो यह प्रतिलिपि निर्माता बेस क्लास कॉपी कन्स्ट्रक्टर (यहां तक ​​कि संश्लेषित एक, अगर उपयोगकर्ता द्वारा कोई भी प्रदान नहीं किया गया है) को कॉल करेगा।

#include <iostream> 

class A { 
    int a; 
public: 
    A() { 
     std::cout << "A::Default constructor" << std::endl; 
    } 

    A(const A& rhs) { 
     std::cout << "A::Copy constructor" << std::endl; 
    } 
}; 

class B : public A { 
    int b; 
public: 
    B() { 
     std::cout << "B::Default constructor" << std::endl; 
    } 
}; 

int main(int argc, const char *argv[]) 
{ 
    std::cout << "Creating B" << std::endl; 
    B b1; 
    std::cout << "Creating B by copy" << std::endl; 
    B b2(b1); 
    return 0; 
} 

आउटपुट:

Creating B 
A::Default constructor 
B::Default constructor 
Creating B by copy 
A::Copy constructor 

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

#include <iostream> 

class A { 
    int a; 
public: 
    A() { 
     std::cout << "A::Default constructor" << std::endl; 
    } 

    A(const A& rhs) { 
     std::cout << "A::Copy constructor" << std::endl; 
    } 
}; 

class B : public A { 
    int b; 
public: 
    B() { 
     std::cout << "B::Default constructor" << std::endl; 
    } 
    B(const B& rhs) { 
     std::cout << "B::Copy constructor" << std::endl; 
    } 
}; 

int main(int argc, const char *argv[]) 
{ 
    std::cout << "Creating B" << std::endl; 
    B b1; 
    std::cout << "Creating B by copy" << std::endl; 
    B b2(b1); 
    return 0; 
} 

आउटपुट:

Creating B 
A::Default constructor 
B::Default constructor 
Creating B by copy 
A::Default constructor 
B::Copy constructor 

मेरा प्रश्न है, क्यों उपयोगकर्ता परिभाषित प्रतिलिपि निर्माता एक डिफ़ॉल्ट व्यवहार के रूप आधार वर्ग प्रति निर्माता फोन नहीं करता है?

+2

यदि यह डिफ़ॉल्ट रूप से उस तरह से था, तो आप उस मामले को कैसे निर्दिष्ट करेंगे जहां आप ऐसा नहीं करना चाहते हैं? प्रारंभकर्ता सूची में – PlasmaHH

+0

@PlasmaHH 'ParentClass()'। यह अभी भी बहुत असंगत और भ्रमित होगा जो मुझे विश्वास है। –

+0

@ मार्कब: दरअसल, मैं उम्मीद कर रहा था कि वह इसके बारे में सोचते समय उसी निष्कर्ष पर आता है ... – PlasmaHH

उत्तर

7

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

1

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

8

सभी मूल बाल निर्माता माता-पिता डिफ़ॉल्ट डिज़ाइनर को कॉल करते हैं। इस प्रकार मानक परिभाषित किया गया है। आप ने कहा के रूप में अगर आप आधार वर्ग बी ए की प्रतिलिपि निर्माता कॉल करने के लिए आप स्पष्ट रूप से पूछने के लिए यह

#include <iostream> 

class A { 
int a; 
public: 
A() { 
    std::cout << "A::Default constructor" << std::endl; 
} 

A(const A& rhs) { 
    std::cout << "A::Copy constructor" << std::endl; 
} 
}; 

class B : public A { 
int b; 
public: 
B() { 
    std::cout << "B::Default constructor" << std::endl; 
} 
B(const B& rhs):A(rhs) { 
    std::cout << "B::Copy constructor" << std::endl; 
} 
}; 

int main(int argc, const char *argv[]) 
{ 
std::cout << "Creating B" << std::endl; 
B b1; 
std::cout << "Creating B by copy" << std::endl; 
B b2(b1); 
return 0; 
} 

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

+5

'सभी मूल बाल रचनाकार माता-पिता डिफ़ॉल्ट डिज़ाइनर को कॉल करते हैं। '... निहित प्रतिलिपि निर्माता को छोड़कर :)! –

+0

लागू प्रतिलिपि कन्स्ट्रक्टर संकलक द्वारा प्रदान किए गए सबसे आदिम संचालन के लिए एक स्पष्ट नाम है, स्रोत की स्रोत की बिटवाई प्रतिलिपि। आईएमओ सिर्फ एक फैंसी नाम है। – shakthi