2010-10-18 20 views
9

MSVC9.0 रनों के साथ संकलित निम्नलिखित कोड और आउटपुट लॉजिकल है।ऑब्जेक्ट ओरिएंटेड आत्महत्या या इसे हटाएं;

#include <iostream> 
class SomeClass 
{ 
public: 
    void CommitSuicide() 
    { 
     delete this; 
    } 
    void Reincarnate() 
    { 
     this->~SomeClass(); 
     new (this) SomeClass; 
    } 
    ~SomeClass() 
    { 
     std::cout << "Destructor\n"; 
    } 
}; 

int main() 
{ 
    SomeClass* p = new SomeClass; 
    p->CommitSuicide(); 
    p = new SomeClass; 
    p->Reincarnate(); 
    p->~SomeClass(); //line 5 
    p->CommitSuicide(); 
} 

मुझे लगता है कि पहले 4 मुख्य में कोड की लाइनों अपरिभाषित व्यवहार में परिणाम नहीं है (हालांकि पूरी तरह delete this; बात के बारे में निश्चित नहीं)। मैं पुष्टिकरण के एंटोनिम> के लिए पुष्टिकरण या < प्लेसहोल्डर रखना चाहता हूं। लेकिन मुझे लाइन 5 और 6 के बारे में गंभीर संदेह है। इसे विनाशक को स्पष्ट रूप से कॉल करने की अनुमति है, है ना? लेकिन क्या उस वस्तु का जीवनकाल उसके बाद खत्म हो गया है? अर्थात, विनाशक (परिभाषित) की स्पष्ट कॉल के बाद किसी अन्य सदस्य का आदान-प्रदान है?

संक्षेप में, उपर्युक्त कोड (यदि कोई है) के कौन से हिस्सों में अपरिभाषित व्यवहार (तकनीकी रूप से बोलने) का परिणाम है?

+0

लेकिन निर्माता को केवल 3 बार कहा जाता है, तो विनाशक को 4 बार तार्किक कैसे कहा जाता है? जैसे ही कक्षा (गैर-तुच्छ) डेटा सदस्यों को मिलती है, यह बम होगा। – visitor

+0

<पुष्टिकरण के एंटोनिम के लिए प्लेसहोल्डर> - इसे "अस्वीकार" कहा जाता है – slashmais

उत्तर

2

पी-> ~ कुछ क्लास(); // लाइन 5

पी-> CommitSuicide(); // लाइन 6

रेखा (6) निश्चित रूप से अनिर्धारित व्यवहार का आह्वान करती है।

क्या विनाशक (परिभाषित) की स्पष्ट कॉल के बाद किसी अन्य सदस्य का आदान-प्रदान है?

नहीं! आपकी धारणा सही है।

+0

लाइन 6 "चाहिए" मेमोरी एक्सेस त्रुटि (लिनक्स पर सेगफॉल्ट) देनी चाहिए क्योंकि पहले से कुछ पता लगाए गए पता स्थान पर पीएल द्वारा इंगित पता स्थान "होना चाहिए" ओएस द्वारा ठीक से मुक्त किया गया। या क्या विनाशक हटाने के लिए देर से कॉल करता है? – slashmais

+0

@ स्लैशमाइस: नहीं, ऐसी कोई गारंटी नहीं है, और बहुत कम कार्यान्वयन इस तरह काम करते हैं। अधिकांश कार्यान्वयनों में "फ्री स्पेस" की धारणा होती है, जिसे ओएस द्वारा प्रोग्राम में आवंटित स्मृति है, फिर भी कोई ऑब्जेक्ट नहीं है। हटाए गए वस्तुओं से पुनः प्राप्त स्मृति को भविष्य में वस्तुओं द्वारा उपयोग किए जाने के लिए इस "मुक्त स्थान" में पुनर्नवीनीकरण किया जाता है। – MSalters

+0

हाँ, मैंने सोचा कि यह ऐसा कुछ होगा। पंक्ति 6 ​​को तब समझाता है क्योंकि अंतरिक्ष अभी तक पुनर्नवीनीकरण नहीं किया गया है। – slashmais

6

delete this; ठीक है। अंतिम p->CommitSuicide(); अपरिभाषित व्यवहार देता है क्योंकि आपने ऑब्जेक्ट को "लाइन 5" में पहले ही नष्ट कर दिया है।

0

"इसे हटाएं" ठीक है जब तक कि आप हटाने के बाद उस वस्तु के किसी भी कोड को कॉल करने का प्रयास नहीं करते हैं (विनाशक भी नहीं)। तो एक स्वयं को हटाने वाली वस्तु को केवल ढेर पर रखा जाना चाहिए और ढेर पर सृजन से बचाने के लिए एक निजी विनाशक है।

मुझे नहीं पता कि विनाशक को सीधा कॉल अपरिभाषित व्यवहार की ओर जाता है लेकिन उपयोगकर्ता परिभाषित डिलीट ऑपरेटर निष्पादित नहीं होता है।

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

  • कोई संबंधित समस्या नहीं^_^