2010-08-06 16 views
7

के बाद स्थानीय चर का उपयोग करना मेरे पास एक कक्षा है जो एक संदर्भ गिनती तंत्र को नियोजित करती है। संदर्भ श्रेणी की संख्या शून्य पर गिरने पर इस वर्ग की वस्तुओं को अंततः delete this पर कॉल करके नष्ट कर दिया जाता है। मेरा सवाल है: क्या मैं delete this के बाद स्थानीय ऑन-स्टैक वैरिएबल का उपयोग कर सकता हूं?"इसे हटाएं"

class RefCountedClass 
{ 
public: 
    RefCountedClass(Mutex& m) : 
     mutex_(m) 
    {} 

    . 
    . 
    . 

private: 
    Mutex& mutex_; 

    void RemoveReference() 
    { 
     // As I understand, mutex_ will be destroyed after delete, 
     // but using m is all right because it is on-stack and 
     // references an external object. Am I right? 
     Mutex& m = mutex_; 
     m.Acquire(); 

     --recount_; 
     if (refcount <= 0) delete this; 

     m.Release(); 
    } 
}; 
+0

होने खुद वस्तुओं गिनती संदर्भ है एक बुरा विचार (यह अगर बता सकते है यह एक स्थिर जीवनकाल (ढेर) या गतिशील जीवनकाल (ढेर) चर है? इस प्रकार COM काम करता है और सी ++ समुदाय द्वारा प्राप्त अनुभवों से हम आगे बढ़े हैं; जैसा कि boost :: shared_ptr से देखा जा सकता है जहां संदर्भ गणना है संदर्भ के संदर्भ में ऑब्जेक्ट का हिस्सा नहीं है। –

+0

@MartinYork मैं आपसे सहमत हूं। एक सामान्य मामले में मैं खुद को ऐसे लागू करने की सलाह नहीं दूंगा संदर्भ गिनती। हालांकि यह एक विशेष मामला है। सौभाग्य से, मेरी असली स्थिति में, निर्माता सार्वजनिक नहीं है और निर्माण कारखाने के वस्तु द्वारा संरक्षित है। मेरे द्वारा – FireAphis

उत्तर

7

हाँ, you may do this, रूप में लंबे समय के रूप में सदस्य चर ही वास्तव में एक बाहरी वस्तु को केवल एक संदर्भ है: एक अधिक सटीक उदाहरण है।

(कृपया पिछले गलत जवाब माफ, मैं mutex_ चर के बारे में उलझन में था।)

+0

+1। मैंने स्थानीय चर को सौंप दिया गया था। मुझे आपका जवाब बेहतर पसंद है, इसलिए मैंने अपना हटा दिया। – Manfred

0

आम तौर पर केवल एक चीज आप delete this के बाद कॉल करने के लिए अनुमति नहीं है कुछ भी है कि this के लिए एक संदर्भ बनाता है। इसमें कोई भी गैर स्थैतिक वर्ग सदस्य या कार्य शामिल है।

आपके मामले में, RemoveReference काम नहीं करेगा एक अच्छा मौका है। यह m अंक mutex_ है जो इसे हटाने के बाद अब मौजूद नहीं है। आपकी सर्वश्रेष्ठ शर्त अच्छी तरह से mutex_ स्थिर बना सकती है।

संपादित करें:mutex_ हालांकि एक बाहरी चर जिसके बाद वर्ग हटा दी जाती है अस्तित्व के लिए जारी है के लिए अंक, वहाँ कोई गारंटी नहीं है कि बुलेटप्रूफ संकलक के बाद वर्ग के मूल्य प्राप्त करने के लिए हटा दिया गया है mutex_ से देख नहीं होगा बाहरी म्यूटेक्स। एक अच्छा मौका है कि चीजें अपेक्षित काम करेगी लेकिन मुझे विश्वास नहीं है कि इसकी गारंटी दी जा सकती है।

+0

नहीं, 'm'' mutex_' को इंगित नहीं करता है, लेकिन जो भी 'mutex_' इंगित करता है: ध्यान दें कि' mutex_' एक संदर्भ है! –

+0

मेरा संपादन देखें - मुझे लगता है कि एक संदर्भ को सूचक के रूप में माना जाता है लेकिन संदर्भ होने के कारण, कंपाइलर mutex_ के मान को कैश कर सकता है और चीजों को अपेक्षित रूप से काम कर सकता है। – doron

+3

यदि संकलक ऐसा करता है जो आप अनुमान लगाते हैं, तो यह टूट जाता है। यह कानूनी सी ++ है। एक और तरीका रखें - यह स्थिति 'int a = myIntegerMemberVariable_ के लिए अलग कैसे है; इसे मिटायें; doSomethingWith (क), '?क्या इस मामले में यह स्पष्ट नहीं है कि कोई भी कंपाइलर जो इसे "अनुकूलित करता है" करने के लिए कुछ करता है (यह-> myIntegerMemberVariable _); 'टूटा हुआ है? –

0

इस मामले में हाँ। आपका स्टैक वैरिएबल 'एम' एक बाहरी संसाधन को इंगित करता है जिसे आप निर्माता

1

हां, आप कर सकते हैं, लेकिन म्यूटेक्स के तहत काउंटर को कम करने के बजाय परमाणु कमी का उपयोग क्यों नहीं कर सकते? और क्या आपको वास्तव में (म्यूटेक्स द्वारा) वस्तु विनाश की रक्षा करने की आवश्यकता है? दरअसल, काउंटर becames 0 के बाद एकमात्र वर्तमान धागा वस्तु को स्वीकार कर सकता है।

तो, शायद यह संभव अपने कोड के पुनर्लेखन के लिए के रूप में

 
    int tmp_count; 
    m.Acquire(); 
     tmp_count= --recount_; 
    m.Release(); 
    if (tmp_count <= 0) delete this; 

(या उपयोग एटोमिक्स घटती और काउंटर परीक्षण करने के लिए)

+1

** खतरनाक **! यह 'tmp_count <= 0' के लिए परीक्षण करने के बाद से डबल-डिलीट हो सकता है। इसके बजाए '== 0' के लिए परीक्षण करना सुरक्षित होगा। लेकिन यह उदाहरण खूबसूरती से दिखाता है कि समवर्ती कोड सही होने के लिए इतना कठिन क्यों है। –

+0

प्रोग्राम में कुछ और बग है (recount_ <0 अन्यथा नहीं हो सकता है) यह खतरनाक है; लेकिन आम तौर पर मैं मानता हूं कि == इस मामले में अधिक स्वीकार्य है। समवर्ती कोड के बारे में +1। ऐसे कोड को एनालिज और सत्यापित करने के लिए समय व्यय 10..20..50 गुना अधिक समय व्यतीत करने के लिए खर्च किया जा सकता है। – user396672

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