लघु उत्तर: हाँ, आप डी में काम दोहराने की आवश्यकता होगी
लांग जवाब:
अपने व्युत्पन्न वर्ग 'डी' कोई नया सदस्य चर तो डिफ़ॉल्ट संस्करणों (संकलक द्वारा उत्पन्न होता है तो ऐसा करना चाहिए काम ठीक है)। डिफ़ॉल्ट प्रतिलिपि निर्माता कंटेंट कॉपी कन्स्ट्रक्टर को कॉल करेगा और डिफ़ॉल्ट असाइनमेंट ऑपरेटर पैरेंट असाइनमेंट ऑपरेटर को कॉल करेगा।
लेकिन यदि आपकी कक्षा 'डी' में संसाधन हैं तो आपको कुछ काम करने की आवश्यकता होगी।
B(const B& b){(*this) = b;}
D(const D& d){(*this) = d;}
आम तौर पर कंस्ट्रक्टर्स श्रृंखला नकल इतना है कि वे बेस से निर्मित कॉपी कर रहे हैं:
मैं आपके प्रति निर्माता थोड़ा अजीब लगता है। यहां क्योंकि आप असाइनमेंट ऑपरेटर को कॉल कर रहे हैं, कॉपी कन्स्ट्रक्टर को डिफॉल्ट कन्स्ट्रक्टर को डिफ़ॉल्ट रूप से ऑब्जेक्ट को पहले नीचे से प्रारंभ करने के लिए कॉल करना होगा। फिर आप असाइनमेंट ऑपरेटर का उपयोग करके फिर से नीचे जाते हैं। यह बल्कि अक्षम है।
अब यदि आप असाइनमेंट करते हैं तो आप नीचे (या ऊपर नीचे) से प्रतिलिपि बना रहे हैं, लेकिन ऐसा करने के लिए आपके लिए मुश्किल लगता है और एक मजबूत अपवाद गारंटी प्रदान करता है। यदि किसी भी समय संसाधन संसाधन की विफलता में विफल रहता है और आप अपवाद फेंकते हैं तो ऑब्जेक्ट एक अनिश्चित स्थिति में होगा (जो एक बुरी चीज है)।
आम तौर पर मैंने इसे दूसरी तरफ देखा है।
असाइनमेंट ऑपरेटर को कॉपी कन्स्ट्रक्टर और स्वैप के संदर्भ में परिभाषित किया गया है। ऐसा इसलिए है क्योंकि यह मजबूत अपवाद गारंटी प्रदान करना आसान बनाता है। मुझे नहीं लगता कि आप इसे इस तरह से कर कर मजबूत गारंटी प्रदान करने में सक्षम होंगे (मैं गलत हो सकता हूं)।
class X
{
// If your class has no resources then use the default version.
// Dynamically allocated memory is a resource.
// If any members have a constructor that throws then you will need to
// write your owen version of these to make it exception safe.
X(X const& copy)
// Do most of the work here in the initializer list
{ /* Do some Work Here */}
X& operator=(X const& copy)
{
X tmp(copy); // All resource all allocation happens here.
// If this fails the copy will throw an exception
// and 'this' object is unaffected by the exception.
swap(tmp);
return *this;
}
// swap is usually trivial to implement
// and you should easily be able to provide the no-throw guarantee.
void swap(X& s) throws()
{
/* Swap all members */
}
};
भले ही आप एक्स से कक्षा डी प्राप्त करते हैं, यह इस पैटर्न को प्रभावित नहीं करता है।
माना जाता है कि आपको बेस क्लास में स्पष्ट कॉल करके काम को थोड़ा सा दोहराना होगा, लेकिन यह अपेक्षाकृत मामूली है।
class D: public X
{
// Note:
// If D contains no members and only a new version of foo()
// Then the default version of these will work fine.
D(D const& copy)
:X(copy) // Chain X's copy constructor
// Do most of D's work here in the initializer list
{ /* More here */}
D& operator=(D const& copy)
{
D tmp(copy); // All resource all allocation happens here.
// If this fails the copy will throw an exception
// and 'this' object is unaffected by the exception.
swap(tmp);
return *this;
}
// swap is usually trivial to implement
// and you should easily be able to provide the no-throw guarantee.
void swap(D& s) throws()
{
X::swap(s); // swap the base class members
/* Swap all D members */
}
};
स्रोत
2009-08-04 10:39:10
यदि आप 'foo' विधि को ओवरराइड करना चाहते हैं, तो आप असाइनमेंट ऑपरेटर के उत्तराधिकारी के लिए' बी :: ऑपरेटर =; 'का उपयोग कर सकते हैं, लेकिन प्रतिलिपि बनाने और चालकों को विरासत में नहीं मिला: https://stackoverflow.com/q/49045026/5447906 –