2012-04-23 8 views
5

जब एक shared_ptr सदस्य चर आरंभ:shared_ptr सदस्य चर प्रारंभ करना, नया बनाम make_shared?

// .h 
class Customer 
{ 
public: 
    Customer(); 

private: 
    std::shared_ptr<OtherClass> something_; 
} 

// .cpp 
Customer(): 
    something_(new OtherClass()) 
{ 
} 

बनाम

Customer(): 
    something_(std::make_shared<OtherClass>()) 
{ 
} 

make_shared संस्करण की अनुमति दी है? मुझे हमेशा पहला संस्करण देखना प्रतीत होता है, जिसे प्राथमिकता दी जाती है?

+4

हर्ब सटर ने अभी इस पर एक गॉट लिखा है। [यह] देखें (http://herbsutter.com/gotw/_103/) और [एक मुद्दा] भी देखें (http://lanzkron.wordpress.com/2012/04/22/make_shared-almost-a-silver -बुललेट /) कि हर्ब स्पष्ट रूप से राज्य नहीं करता है। –

+0

@RSamuelKlatchko - आपके उत्तरदाता में दिए गए पहले लिंक के लिए एक अपडेट किया गया लिंक https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ –

उत्तर

11

केवल बार जब make_sharedअनुमति नहीं है कर रहे हैं:

  1. आप एक नग्न सूचक बाकी और shared_ptr में भंडारण किसी के द्वारा आवंटित मिल रहे हैं। सी एपीआई के साथ इंटरफेसिंग करते समय यह अक्सर होता है।
  2. यदि आप जिस निर्माता को कॉल करना चाहते हैं वह सार्वजनिक नहीं है (make_shared केवल सार्वजनिक निर्माता ही कॉल कर सकता है)। यह कारखाने के कार्यों के साथ हो सकता है, जहां आप कारखाने से वस्तु बनाने के लिए उपयोगकर्ताओं को मजबूर करना चाहते हैं।

    हालांकि, इसके आसपास जाने के तरीके हैं। एक निजी कन्स्ट्रक्टर रखने के बजाय, एक सार्वजनिक कन्स्ट्रक्टर है। लेकिन कन्स्ट्रक्टर को एक प्रकार का प्रकार लेना चाहिए जिसे केवल वर्ग तक निजी पहुंच वाले लोगों द्वारा बनाया जा सकता है। इस तरह, केवल वे लोग जो make_shared को उस ऑब्जेक्ट प्रकार के साथ कॉल कर सकते हैं वे कक्षा में निजी पहुंच वाले हैं।

तो हाँ, आप यह कर सकते हैं।

+0

दोस्ती के मुद्दे के बारे में, क्या कोई है दोस्तों के रूप में उपयोग करने के लिए विशेष समारोह के मानक में उल्लेख करें? मैं इस काम को सहायक कार्यों में सौंपने वाले कुछ कार्यान्वयन की कल्पना कर सकता हूं ... –

+0

@MatthieuM .: मैं थोड़ी सी सोच रहा था, इसलिए मैंने कहा "सक्षम हो सकता है"। मैंने comp.std.C++ पर पूछा है; हम देखेंगे कि उन्हें इसके बारे में क्या कहना है। यदि नहीं, तो मुझे लगता है कि यह एक सभ्य दोष रिपोर्ट के लिए बना सकता है। –

3

इस मामले में, make_shared का उपयोग करने की अनुमति नहीं है, लेकिन इसका उपयोग करना बेहतर है। यदि आप नए का उपयोग करते हैं, तो यह कहीं भी आपके ग्राहक के लिए स्मृति आवंटित करेगा और फिर आपके साझा_प्टर के लिए स्मृति कहीं और मजबूत, कमजोर संदर्भ दोनों (कमजोर पॉइंटर्स और साझा पॉइंटर्स के लिए) संग्रहीत करेगा। यदि आप make_shared का उपयोग करते हैं तो आपके पास सब कुछ के साथ स्मृति में केवल एक ही स्थान होगा और इसलिए केवल एक नया होगा।

मुझे यकीन नहीं है कि मैं वास्तव में स्पष्ट था, यह GotW #103 का उद्देश्य था, इसे पढ़ें, यह अच्छी तरह से समझाया गया है।

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