11
#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
}; 
class derv :public base 
{ 
    int b; 
    public: 
    derv() {b =1;} 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

मेरे पास डर्व क्लास में वर्चुअल विनाशक नहीं है, क्या यह केवल डर्व ऑब्जेक्ट का मूल भाग हटा देता है ??वर्चुअल विनाशक के बिना संभावित स्मृति रिसाव?

+0

यह आधार वर्ग है जिसे आभासी विनाशक की आवश्यकता है। – Yuushi

+0

@ मिस्टिकियल: जेम्स के पास यह है। – Puppy

+0

@ जेम्स, आपने कहा कि बेस क्लास में कोई वर्चुअल फ़ंक्शन नहीं है लेकिन यदि हम बेस क्लास का उत्तराधिकारी बनाना चाहते हैं तो इसमें वर्चुअल विनाशक होना चाहिए ?? – Alok

उत्तर

19

यह हो सकता है।

क्योंकि base में कोई वर्चुअल विनाशक नहीं है, तो आपका कोड अपरिभाषित व्यवहार प्रदर्शित करता है। कुछ भी हो सकता है। जैसा कि आप उम्मीद करते हैं यह काम करने के लिए प्रतीत होता है। यह स्मृति रिसाव हो सकता है। यह आपके प्रोग्राम को दुर्घटनाग्रस्त कर सकता है। यह आपकी हार्ड ड्राइव को प्रारूपित कर सकता है।

एक उद्धरण का अनुरोध किया गया था। सी ++ 11 §5.3.5/3 कहा गया है कि, एक अदिश delete अभिव्यक्ति (यानी, नहीं एक delete[] अभिव्यक्ति) के लिए:

अगर वस्तु के स्थिर प्रकार हटाए जाने के लिए अपनी गतिशील प्रकार से अलग है, स्थिर प्रकार किया जाएगा वस्तु की गतिशील प्रकार का एक आधार वर्ग हटाए जाने के लिए और स्थिर प्रकार एक आभासी नाशक होगा या व्यवहार अनिर्धारित रहता है।

स्थिर प्रकार (base) गतिशील प्रकार (derv) और स्थिर प्रकार एक आभासी नाशक नहीं है से अलग है, तो व्यवहार अनिर्धारित रहता है।

+2

बेस में आभासी विनाशक की कमी का मतलब है कि व्युत्पन्न वर्गों के विनाशक में निर्दिष्ट कोई भी कस्टम अंतिम रूप निष्पादित नहीं होगा। ऑब्जेक्ट के लिए स्मृति अभी भी सही ढंग से हटा दी जाएगी। ('आधार' के विनाशक को भी बुलाया जाएगा यदि इसे गैर-वर्चुअल द्वारा परिभाषित किया गया था)। – Xion

+6

@Xion: वास्तव में। व्यवहार अपरिभाषित है। सभी दांव बंद हैं। कार्यक्रम के व्यवहार के बारे में निश्चितता के साथ कुछ भी नहीं कहा जा सकता है। –

+2

संदर्भ, कृपया! – wilhelmtell

-1

आपके कोड में कोई स्मृति रिसाव नहीं है। यदि आपको व्युत्पन्न वर्ग विनाशक में कुछ स्मृति मुक्त करने की आवश्यकता होती है तो एक स्मृति रिसाव होता।

+6

व्यवहार अपरिभाषित है। सभी दांव बंद हैं। कार्यक्रम के व्यवहार के बारे में निश्चितता के साथ कुछ भी नहीं कहा जा सकता है। –

-1

अपने स्रोत कोड में, कोई स्मृति रिसाव है जब से तुम जो गतिशील रूप से बनाई गई है किसी भी सदस्य चर नहीं है। ,

#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
    ~base() 
    { 
     cout<<"\nBase Destructor called"; 

    } 
}; 
class derv :public base 
{ 
    int *b; 

    public: 
    derv() { b = new int;} 
    ~derv() 
    { 
     cout<<"\nDerv Destructor called"; 
     delete b; 
    } 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

इस मामले व्यवहृत किया जा सकेगा में,

Base Destructor called 

इस मामले में एक स्मृति रिसाव होती है क्योंकि 'बी' डायनामिक रूप से तैयार किया गया है:

केस 1 नीचे संशोधित उदाहरण पर विचार करें 'नया' का उपयोग करके जिसे 'हटाएं' कीवर्ड का उपयोग करके हटाया जाना चाहिए। चूंकि डर्व विनाशक को नहीं कहा जा रहा है क्योंकि इसे हटाया नहीं गया है इसलिए स्मृति रिसाव है।

नीचे मामले 2 पर विचार करें:

#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
    virtual ~base() 
    { 
     cout<<"\nBase Destructor called"; 

    } 
}; 
class derv :public base 
{ 
    int *b; 

    public: 
    derv() { b = new int;} 
    ~derv() 
    { 
     cout<<"\nDerv Destructor called"; 
     delete b; 
    } 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

मामले 2 व्यवहृत किया जा सकेगा में,

Derv Destructor called 
Base Destructor called 

इस मामले में वहाँ derv नाशक leak.because कोई स्मृति कहा जाता है और ख हो रही है नष्ट कर दिया।

नाशक यकीन है कि व्युत्पन्न वर्ग नाशक जब हम आधार वर्ग सूचक जो व्युत्पन्न वर्ग वस्तु की ओर इशारा करते है को नष्ट करने के लिए कहा जा करने के लिए आधार वर्ग में आभासी रूप में परिभाषित किया जा सकता है।

हम कह सकते हैं कि जब व्युत्पन्न वर्ग ने गतिशील रूप से सदस्यों को बनाया है तो विनाशक आभासी होना चाहिए।

+1

व्यवहार अपरिभाषित है। सभी दांव बंद हैं। कार्यक्रम के व्यवहार के बारे में निश्चितता के साथ कुछ भी नहीं कहा जा सकता है। –

+1

@JamesMcNellis: उपर्युक्त कोड में जिसमें व्युत्पन्न कक्षा में स्मृति आवंटन होता है, में आभासी विनाशक होना चाहिए। अन्यथा एक स्मृति रिसाव है। –

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