अगले दो वर्गों को ध्यान में रखते हुए:

struct Base
{
  virtual ~Base()
  {
  }

  virtual void foo() = 0;
};

struct Derived : public Base
{
  virtual void foo()
  {
  }
};

निम्नलिखित एक अपरिभाषित व्यवहार पैदा कर रहा है:

Base *obj = new Derived;
delete obj;

?

अतिरिक्त प्रश्न: कैसे एक विधि को आभासी घोषित किया जाता है, यह व्युत्पन्न कक्षाओं में आभासी है (भले ही व्युत्पन्न वर्ग में वर्चुअल कीवर्ड का उपयोग न किया गया हो), लेकिन यह विनाशकों के लिए सच नहीं है?

0
BЈовић 19 अप्रैल 2011, 15:53

4 जवाब

सबसे बढ़िया उत्तर

निम्नलिखित एक अपरिभाषित व्यवहार पैदा कर रहा है:

नहीं, यह अपरिभाषित व्यवहार का आह्वान नहीं कर रहा है ठीक क्योंकि Base का विनाशक virtual है।


संपादित करें: यह सिर्फ एक संदेह को स्पष्ट करने के लिए है (निम्नलिखित टिप्पणी में उठाया गया है), और जो मैंने ऊपर कहा है उस पर जोर देने के लिए।

@ ओली चार्ल्सवर्थ ने टिप्पणी की:

तकनीकी रूप से, भले ही इसे वर्चुअल घोषित न किया गया हो, व्यवहार अपरिभाषित होगा, यह केवल अवांछनीय होगा।

नहीं। व्यवहार अपरिभाषित होगा।

मानक से खंड 5.3.5/3 कहता है,

पहले विकल्प में (हटाएं ऑब्जेक्ट), यदि स्थिर प्रकार का संकार्य इसके गतिशील से अलग है प्रकार, स्थिर प्रकार आधार होगा ऑपरेंड के गतिशील प्रकार का वर्ग और स्थिर प्रकार होगा a आभासी विनाशक <मजबूत>या व्यवहार अपरिभाषित है। दूसरे विकल्प में (सरणी हटाएं) यदि गतिशील प्रकार का हटाए जाने वाली वस्तु अपने स्थिर प्रकार से भिन्न होती है, व्यवहार अपरिभाषित होता है।

मुझे लगता है कि यह संदेह को दूर करने में मदद करता है। :-)

4
Nawaz 19 अप्रैल 2011, 16:24

वह अपरिभाषित व्यवहार नहीं है। आपने बेस-क्लास डिस्ट्रक्टर को virtual के रूप में घोषित किया है, इसलिए रनटाइम पर, delete obj पहले Derived में "डिफॉल्ट" डिस्ट्रक्टर को इनवाइट करेगा (जैसा कि आपने स्पष्ट रूप से एक घोषित नहीं किया है), और फिर Base में विनाशक।

2
Oliver Charlesworth 19 अप्रैल 2011, 15:55

चूंकि आपने बेस क्लास के विनाशक को आभासी घोषित किया है, यहां कोई अपरिभाषित व्यवहार नहीं है।

बयान:

Base *obj = new Derived;
delete obj;

व्युत्पन्न वर्ग के विनाशक और फिर बेस क्लास के विनाशक को कॉल करने के लिए नेतृत्व करेगा। हालांकि मुझे दूसरा सवाल नहीं मिला

1
mukeshkumar 19 अप्रैल 2011, 15:59

किसी भी वर्ग के लिए, कंस्ट्रक्टर और डिस्ट्रक्टर विरासत में नहीं हैं। यह मानक में निर्दिष्ट है। इस प्रकार, आपका कोड अपरिभाषित व्यवहार का कारण नहीं बनेगा, क्योंकि यह वर्ग के लिए डिफ़ॉल्ट कंस्ट्रक्टर/डिस्ट्रक्टर को लागू करेगा।
यही कारण है कि विरासत विनाशकों/निर्माताओं के लिए सही नहीं है। किसी निर्माता/विनाशक को मूल वस्तु से विरासत में प्राप्त करने का कोई मतलब नहीं है, क्योंकि इस वस्तु में संभावित रूप से विभिन्न सदस्यों के सभी रूप हो सकते हैं।

1
Ben Stott 19 अप्रैल 2011, 16:00