2011-06-15 30 views
5

सी ++ मानक (आईएसओ/आईईसी 14882: 2003 (ई)) से हटा दें §12.5.4, operator delete अधिक भार के बारे में:ओवरलोडिंग ऑपरेटर एक आधार वर्ग

हटाएं अभिव्यक्ति एक एकल से शुरू होता है :: ऑपरेटर, डीलोकेशन फ़ंक्शन का नाम वैश्विक दायरे में देखा जाता है। अन्यथा, यदि डिलीवरी-अभिव्यक्ति का उपयोग किसी क्लास ऑब्जेक्ट को डिलीकेट करने के लिए किया जाता है जिसका स्थिर प्रकार वर्चुअल विनाशक होता है, तो डेलोकेशन फ़ंक्शन गतिशील प्रकार के आभासी विनाशक (12.4) की परिभाषा में लुकअप द्वारा पाया जाता है। अन्यथा, यदि हटाई-अभिव्यक्ति का उपयोग वर्ग टी या सरणी के किसी ऑब्जेक्ट को डिलीकेट करने के लिए किया जाता है, तो वस्तु के स्थिर और गतिशील प्रकार समान होंगे और डीलोकेशन फ़ंक्शन का नाम टी के दायरे में देखा जाएगा। यदि यह लुकअप विफल रहता है नाम खोजने के लिए, नाम वैश्विक दायरे में देखा गया है। यदि लुकअप का परिणाम संदिग्ध या पहुंच योग्य नहीं है, या यदि लुकअप प्लेसमेंट डेलोकेशन फ़ंक्शन का चयन करता है, तो प्रोग्राम खराब बना हुआ है।

§12.5.7 भी दिलचस्प है:

के बाद से सदस्य आवंटन और आवंटन रद्द करने कार्यों स्थिर हैं वे आभासी नहीं हो सकता। [नोट: हालांकि, जब एक डिलीट-एक्सप्रेशन की कास्ट-एक्सप्रेशन क्लास प्रकार की ऑब्जेक्ट को संदर्भित करती है, क्योंकि वास्तव में डेलोकेशन फ़ंक्शन को कक्षा के दायरे में देखा जाता है जो ऑब्जेक्ट का गतिशील प्रकार होता है, यदि विनाशक आभासी है, प्रभाव वही है। उदाहरण के लिए,

struct B { 
    virtual ˜B(); 
    void operator delete(void*, size_t); 
}; 
struct D : B { 
    void operator delete(void*); 
}; 
void f() 
{ 
    B* bp = new D; 
    delete bp; // uses D::operator delete(void*) 
} 

यहाँ, वर्ग डी की गैर सरणी वस्तु के लिए भंडारण D से पुनः आवंटित की जाती है :: ऑपरेटर आभासी नाशक की वजह से हटाना(),।]

इसे पढ़ने के बाद, मैं सोच रहा हूं ...

  • क्या मानक का यह हिस्सा पूरी तरह से सभी प्रमुख सी ++ कंपाइलर्स (एमएसवीसी ++, जीसीसी) द्वारा समर्थित है?
  • यदि हां, तो उन्होंने यह कैसे किया? छुपे हुए वर्चुअल फ़ंक्शन? "विशेष" आभासी विनाशक कॉल? RTTI?
  • मानक से उदाहरण का उपयोग करना: क्या समस्याएं हो सकती हैं यदि f() और D :: ऑपरेटर डिलीट() को अलग EXE/DLL/DSO में परिभाषित किया गया है? (यह मानते हुए कि सब कुछ जाहिर है, एक ही संकलक का उपयोग कर संकलित किया गया है)

§5.3.5.5 भी प्रासंगिक हो सकता है:

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

+0

मेरा अनुमान है: वे वर्चुअल टेबल पर चलते हैं। जैसा कि मानक कहता है, कक्षा को सही तरीके से काम करने के लिए एक आभासी विनाशक होना चाहिए। यह 'हटाएं' के गैर-अधिभारित संस्करण के लिए भी सच है। – Xeo

+0

मैंने जवाब देने का प्रयास किया लेकिन ऐसा लगता है कि आप वास्तव में जीसीसी स्रोत कोड में देखने और आपको वापस रिपोर्ट करने के लिए चाहते हैं। मुझे लगता है कि आप इसे स्वयं कर सकते हैं। – littleadv

उत्तर

6

मुझे वीसी ++ एबीआई के बारे में बहुत कुछ पता नहीं है, लेकिन Itanium एबीआई अच्छी तरह से प्रलेखित है।

the name mangling scheme पर देखने से, देखें:

<ctor-dtor-name> ::= C1  # complete object constructor 
       ::= C2  # base object constructor 
       ::= C3  # complete object allocating constructor 
       ::= D0  # deleting destructor 
       ::= D1  # complete object destructor 
       ::= D2  # base object destructor 
रुचि का

: D0 # deleting destructor, जिसका अर्थ है कि भले ही delete, गैर आभासी है, क्योंकि यह आभासी नाशक से कहा जाता है, यह सभी के लिए आभासी माना जा सकता है प्रभाव और उद्देश्यों।

+0

यह दिलचस्प है, धन्यवाद। मैं आपके उत्तर को स्वीकार्य रूप से चिह्नित कर दूंगा, कम से कम जब तक कि कोई अधिक x86-विशिष्ट उत्तर के साथ न आए। –

+1

@ ई-टी 172: मुझे नहीं लगता कि आपको 'x86' (प्रोसेसर) विशिष्ट उत्तर की आवश्यकता होगी। यह एक उच्च स्तरीय निर्णय है, और हालांकि यह एबीआई को दिखाता है, मुझे गंभीरता से संदेह है कि वीसी ++, जीसीसी या क्लैंग इसके लिए बैकएंड में विशिष्ट कार्य-आसपास लागू करेगा। –

0

विधानसभा कोड में खुदाई के बाद जीसीसी 4.8 से फेंकना

जीसीसी कोड के दो टुकड़े उत्पन्न होगा में (वर्ग जिसका नाशक के लिए आभासी है):

One is assembly snippet#1 for {Destructor + Dealloc} 
The other is assembly snippet#2 for {Destructor only} 

और वर्ग जिसका नाशक है के लिए वर्चुअल नहीं, कॉल डेलोकेशन फ़ंक्शन निर्देश उस बिंदु पर उत्पन्न होगा जहां आप डिलीट करते हैं।

delete C // This will be translate as call snippet#1 for the correct dynamic type 

और अगर आप कोड पीछा कर रहा है:

तो कोड निम्न के लिए (चर्चा मान नाशक आभासी है के बाद)

p->C::~C() // this will be translate to call snippet#2 

तो पुनःआवंटन समारोह आभासी के साथ एक साथ बाँध है नाशक। तो मुझे लगता है कि यह आपके प्रश्न का उत्तर देगा कि कैसे deallocate फ़ंक्शन आभासी लेकिन स्थिर भी लागू होते हैं।

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