2010-07-09 11 views
7

के मौजूदा उदाहरण पर हटाए गए क्रिया को बदलने का कोई तरीका है मेरे पास एक ऐसा कार्य है जहां मैं क्लीनअप कार्रवाई 90% करता हूं, लेकिन 10% में मैं कुछ अन्य कार्यवाही करना चाहता हूं।क्या साझा_ptr

क्या कुछ मानक स्कॉप्ड नियंत्रण का उपयोग करने के लिए shared_ptr<> का उपयोग करने का कोई तरीका है ताकि प्रारंभ में इसमें एक हटाई गई कार्रवाई हो और बाद में फ़ंक्शन में हटाए गए क्रिया को बदला जा सके?

shared_ptr<T> ptr(new T, std::mem_fun_ref(&T::deleteMe)); 
ptr.pn.d = std::mem_fun_ref(&T::queueMe); 
+2

क्यों अपने कस्टम डिलीटर में अपनी हटाने की रणनीतियों को लागू नहीं करते? – Abhay

+0

मैं केवल कस्टम डिलीटर लिखने से बचने की कोशिश कर रहा था जब मुझे केवल 2 सदस्य फ़ंक्शंस के बीच (वर्तमान में) चुनने की आवश्यकता थी। –

उत्तर

2

मुझे नहीं लगता कि आप Deleter बदल सकते हैं एक बार shared_ptr बनाया गया था है।

लेकिन आप ऐसा क्यों करेंगे? आम तौर पर, जब आप कोई ऑब्जेक्ट बनाते हैं, तो आप तुरंत जानते हैं कि इसे कैसे नष्ट किया जाना चाहिए। यह बदलने की संभावना नहीं है।

यदि आपको वास्तव में कुछ विशिष्ट उपचार करना चाहिए, तो भी आप एक कस्टम डिलीटर प्रदान कर सकते हैं जो आवश्यक तर्कों के आधार पर विशेष चीजें करता है।

+2

मैंने अभी एक कारण के बारे में सोचा है, जो कि आप संभवतः विलेटर को एक नए डिलीटर के साथ प्रतिस्थापित करना चाहते हैं जो पुराने व्यक्ति करता है, * और * कुछ और (जैसे ऑब्जेक्ट विनाश के श्रोता को सूचित करता है)। लेकिन मुझे पूरा यकीन है कि यह व्यवहार्य नहीं है, अगर केवल इसलिए कि डिलीटर नियंत्रण ब्लॉक में है, तो आप निश्चित रूप से इसे एक अलग आकार के साथ एक डिलीटर के साथ प्रतिस्थापित नहीं कर सके। तो आप कहते हैं, इस व्यवहार की संभावना शुरुआत से ही 'shared_ptr' में होना चाहिए। –

+0

उपयोग का मामला मैं सोच सकता हूं कि आपके पास एक लाइब्रेरी है जो एक std :: tr1 :: shared_ptr देता है और आप एक std :: shared_ptr पर नियंत्रण ले जाना चाहते हैं और आपको विश्वास है कि std :: shared_ptr outlast std :: tr1 :: shared_ptr। भयानक? पूर्ण रूप से। –

2

डिलीटर बदलने की आवश्यकता के लिए एक वैध कारण है। उदाहरण के लिए इसे लें:

int foo(std::shared_ptr<double>& bar) { 
    ... 
    std::shared_ptr<double> p(my_allocator<double>::allocate(), my_deleter<double>()); 
    bar.swap(p); // this copies the deleter 
    ... 
} 

int main(int, char**) { 
    std::shared_ptr<double> d; 
    foo(d); // d now has a new deleter that will be called when it goes out of scope 
    ... 
} 

इस मामले में foo() फ़ंक्शन कुछ विशेष आवंटकों का उपयोग करके डबल * आवंटित करता है। इसे उस स्मृति को एक विशेष तरीके से मुक्त करने की भी आवश्यकता है। कॉलर को यह जानने की आवश्यकता नहीं है कि स्मृति को कैसे मुक्त किया जाए।

+0

यहां कुछ भी नहीं बदला जाता है। आप एक नया 'std :: shared_ptr' बना रहे हैं, और उसके बाद इसे किसी भी अन्य मूल्य वस्तु की तरह उपयोग कर रहे हैं। –

+0

@ क्यूबा-ओबर: मैं देखता हूं, मैंने अपने मूल प्रश्न को गलत समझा। आप सही हैं, वह निश्चित रूप से मौजूदा पॉइंटर के लिए हटाए जाने के बाद मौजूदा शेयर_प्टर ऑब्जेक्ट (जैसे शीर्षक कहता है) पर डिलीटर को अपडेट करने के बजाय डिलीटर को बदलना चाहता है। –

0

यह कोई समझ नहीं आता है, क्योंकि shared_ptr की कोई भी संख्या मूल्य के स्वामित्व का प्रबंधन करती है। आपको उन सभी को संशोधित करने की आवश्यकता होगी, और यह संभव नहीं है। चलो भूलें कि एक नियंत्रण ब्लॉक एक कार्यान्वयन विस्तार है, इसलिए "आह, लेकिन इसे नियंत्रण ब्लॉक में बदलना" काम नहीं करेगा।

हटाए गए कार्यों को shared_ptr के स्वामित्व वाले उदाहरण द्वारा नियंत्रित किया जाना चाहिए, उदा।

class C { 
... 
    void (C::action*)() { &C::action1 }; 
    void action1(); 
    void action2(); 
    ~C() { (this->*action)(); } 
}; 

void test() { 
    std::shared_ptr<C> a; 
    a->action = &C::action2; 
    // action2 gets invoked once `a` falls out of scope 
} 
संबंधित मुद्दे