2011-11-20 7 views
6

मेरे पास resource_manager कक्षा है जो आंतरिक रूप से std::vector<boost::shared_ptr<resource> > रखती है। resource_managerresource का मित्र वर्ग है। मैं resource एस को केवल resource_manager द्वारा बनाया/हटाया जाना चाहता हूं, इसलिए मैंने अपने रचनाकारों को निजी बनाया (जो ठीक काम करता है)।मैं share_ptr से निजी विनाशक कैसे कॉल कर सकता हूं?

हालांकि, अगर मैं विनाशक निजी बनाता हूं, तो कोड संकलित नहीं होता है क्योंकि विनाशक को boost::shared_ptr द्वारा बुलाया जाता है, जो resource का मित्र नहीं है। मैं resource_manager से केवल const resource* लौटकर "ग्राहकों द्वारा डिलीट न करें" नियम लागू करने के बारे में सोच रहा हूं, लेकिन किसी भी तरह से मैं इस विधि की सुरक्षा से संतुष्ट नहीं हूं (क्या होगा यदि क्लाइंट किसी भी तरह से पॉइंटर में गैर-कॉन्स में होता है?)

shared_ptr का उपयोग न करने के स्पष्ट समाधान के अलावा, क्या आपके पास मेरी समस्या का कोई समाधान/बेहतर समाधान है?

+0

एक ही रास्ता "ग्राहक किसी भी तरह गैर स्थिरांक के लिए सूचक भर में होता है" वे कर सकता है कि अगर है: तो सिर्फ एक Deleter functor या समारोह (आप पर निर्भर) जो बदले में अपने वर्ग के एक friend है बनाने वे const_cast का उपयोग कर कास्ट किया। "सुरक्षा" परिप्रेक्ष्य से कच्चे पॉइंटर्स और shared_ptr के बीच कोई अंतर नहीं है, अंतर जीवन-समय प्रबंधन में निहित है, जिसमें से मुझे यकीन नहीं है कि आप share_ptr के बिना कैसे संभालेंगे। – ronag

+4

ए 'कॉन्स संसाधन * का मतलब यह नहीं है कि आप इसे हटा नहीं सकते हैं। – UncleBens

+0

@UncleBens: यह नहीं है? मैंने सोचा कि संकलक आपको किसी नॉन-कॉन्स्ट फ़ंक्शन को कॉन्स्ट पर कॉल करने की अनुमति नहीं दे सकता है! क्या मैं गलत हूँ? या यह नियम विनाशक पर लागू नहीं होता है? –

उत्तर

11

आप साझा पॉइंटर को कस्टम डिलीटर पास कर सकते हैं।

class Secret 
{ 
    ~Secret() { } 
    friend class SecretDeleter; 
    friend void SecretDelFunc(Secret *); 
}; 

class SecretDeleter 
{ 
public: 
    void operator()(Secret * p) { delete p; } 
}; 

void SecretDelFunc(Secret * p) { delete p; } 

std::shared_ptr<Secret> sp1(new Secret, SecretDeleter()); 
std::shared_ptr<Secret> sp2(new Secret, SecretDelFunc); 
+0

की कोशिश की तो यह काम नहीं प्रतीत होता है आप एक ही विचार के साथ मुझसे हमेशा तेज क्यों हैं? बंद करो! :( – Xeo

+0

@Xeo: बेहतर केक का एक अलग टुकड़ा चुनें - मेरी आंखें दृढ़ता से 'shared_ptr' पर हैं! ;-) –

+1

बीटीडब्ल्यू, आपको 'SecretDeleter' को तुरंत चालू करना चाहिए। – Xeo

1

शायद shared_ptr<resource> दोस्त के रूप में घोषित करें? shared_ptr कन्स्ट्रक्टर को कॉल नहीं करता है, और केवल तभी नष्ट होना चाहिए जब आपके संसाधन प्रबंधक पॉइंटर को रिलीज़ करते हैं, इससे पहले कि सभी क्लाइंट ने अपने shared_ptrs को नष्ट कर दिया हो। यह ग्राहकों को सुरक्षा तोड़ने की अनुमति नहीं देगा, लेकिन ग्राहकों को resource_manager की "इच्छा" के खिलाफ संसाधन को जीवित रखने की अनुमति देगा।

+0

जब मैंने –