अगले दो वर्गों को ध्यान में रखते हुए:
struct Base
{
virtual ~Base()
{
}
virtual void foo() = 0;
};
struct Derived : public Base
{
virtual void foo()
{
}
};
निम्नलिखित एक अपरिभाषित व्यवहार पैदा कर रहा है:
Base *obj = new Derived;
delete obj;
?
अतिरिक्त प्रश्न: कैसे एक विधि को आभासी घोषित किया जाता है, यह व्युत्पन्न कक्षाओं में आभासी है (भले ही व्युत्पन्न वर्ग में वर्चुअल कीवर्ड का उपयोग न किया गया हो), लेकिन यह विनाशकों के लिए सच नहीं है?
4 जवाब
निम्नलिखित एक अपरिभाषित व्यवहार पैदा कर रहा है:
नहीं, यह अपरिभाषित व्यवहार का आह्वान नहीं कर रहा है ठीक क्योंकि Base
का विनाशक virtual
है।
संपादित करें: यह सिर्फ एक संदेह को स्पष्ट करने के लिए है (निम्नलिखित टिप्पणी में उठाया गया है), और जो मैंने ऊपर कहा है उस पर जोर देने के लिए।
@ ओली चार्ल्सवर्थ ने टिप्पणी की:
तकनीकी रूप से, भले ही इसे वर्चुअल घोषित न किया गया हो, व्यवहार अपरिभाषित होगा, यह केवल अवांछनीय होगा।
नहीं। व्यवहार अपरिभाषित होगा।
मानक से खंड 5.3.5/3 कहता है,
पहले विकल्प में (हटाएं ऑब्जेक्ट), यदि स्थिर प्रकार का संकार्य इसके गतिशील से अलग है प्रकार, स्थिर प्रकार आधार होगा ऑपरेंड के गतिशील प्रकार का वर्ग और स्थिर प्रकार होगा a आभासी विनाशक <मजबूत>या व्यवहार अपरिभाषित है। दूसरे विकल्प में (सरणी हटाएं) यदि गतिशील प्रकार का हटाए जाने वाली वस्तु अपने स्थिर प्रकार से भिन्न होती है, व्यवहार अपरिभाषित होता है।
मुझे लगता है कि यह संदेह को दूर करने में मदद करता है। :-)
वह अपरिभाषित व्यवहार नहीं है। आपने बेस-क्लास डिस्ट्रक्टर को virtual
के रूप में घोषित किया है, इसलिए रनटाइम पर, delete obj
पहले Derived
में "डिफॉल्ट" डिस्ट्रक्टर को इनवाइट करेगा (जैसा कि आपने स्पष्ट रूप से एक घोषित नहीं किया है), और फिर Base
में विनाशक।
चूंकि आपने बेस क्लास के विनाशक को आभासी घोषित किया है, यहां कोई अपरिभाषित व्यवहार नहीं है।
बयान:
Base *obj = new Derived;
delete obj;
व्युत्पन्न वर्ग के विनाशक और फिर बेस क्लास के विनाशक को कॉल करने के लिए नेतृत्व करेगा। हालांकि मुझे दूसरा सवाल नहीं मिला
किसी भी वर्ग के लिए, कंस्ट्रक्टर और डिस्ट्रक्टर विरासत में नहीं हैं। यह मानक में निर्दिष्ट है। इस प्रकार, आपका कोड अपरिभाषित व्यवहार का कारण नहीं बनेगा, क्योंकि यह वर्ग के लिए डिफ़ॉल्ट कंस्ट्रक्टर/डिस्ट्रक्टर को लागू करेगा।
यही कारण है कि विरासत विनाशकों/निर्माताओं के लिए सही नहीं है। किसी निर्माता/विनाशक को मूल वस्तु से विरासत में प्राप्त करने का कोई मतलब नहीं है, क्योंकि इस वस्तु में संभावित रूप से विभिन्न सदस्यों के सभी रूप हो सकते हैं।
संबंधित सवाल
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।