2010-01-27 8 views
51

बनाने के लिए make_shared का उपयोग करने के साथ कोई डाउनसाइड्स हैं shared_ptr<T>(new T) का उपयोग करने के बजाय make_shared<T>() का उपयोग करने के साथ कोई डाउनसाइड्स हैं।क्या साझा_ptr

Boost documentation राज्यों

वहाँ एक कारखाने समारोह है कि एक दिया प्रकार और रिटर्न इसे करने के लिए एक shared_ptr की एक वस्तु बनाता है के लिए उपयोगकर्ताओं से अनुरोध दोहराया गया है। सुविधा और शैली इसके अलावा, इस तरह के एक समारोह भी अपवाद सुरक्षित और काफी तेज है, क्योंकि यह दोनों वस्तु और उसके संगत नियंत्रण ब्लॉक के लिए एक भी आवंटन, shared_ptr के निर्माण भूमि के ऊपर का एक महत्वपूर्ण भाग को नष्ट करने का उपयोग कर सकते हैं। यह shared_ptr के बारे में प्रमुख दक्षता शिकायतों में से एक को समाप्त करता है।

+6

एक आश्चर्य हो सकता है, shared_ptr के बारे में अन्य प्रमुख दक्षता शिकायतें क्या हैं? –

+0

अपवाद सुरक्षा 'std :: make_shared' की एक सुंदर मजबूत * संपत्ति * है। जब भी संभव हो इसका उपयोग करने का प्रयास करें। –

+0

संदर्भ काउंटर पर @ViktorSehr Mutex ताले जब एक 'shared_ptr' कॉपी किया जाता है मुख्य रूप से :) – Drax

उत्तर

26

मुझे कम से कम दो पता है।

  • आपको आवंटन के नियंत्रण में होना चाहिए। वास्तव में कोई बड़ा नहीं, लेकिन कुछ पुराने एपीआई पॉइंटर्स को वापस करना पसंद करते हैं जिन्हें आपको हटाना होगा।
  • कोई कस्टम डिलीटर नहीं। मुझे नहीं पता कि यह क्यों समर्थित नहीं है, लेकिन यह नहीं है। इसका मतलब है कि आपके साझा पॉइंटर्स को वेनिला डिलीटर का उपयोग करना होगा।

बहुत कमजोर अंक। इसलिए हमेशा make_shared का उपयोग करने का प्रयास करें।

+6

कोई कस्टम Deleter क्योंकि केवल 'make_shared' ही कैसे वस्तु को हटाने के लिए जानता है। –

+4

कस्टम डिलीटर का उपयोग कुछ रोचक चालों को करने के लिए किया जाता है जो केवल हटाने के लिए ही सीमित नहीं है, यही कारण है कि deft_code ने इसका उल्लेख किया। – Catskul

+0

यदि आप कस्टम डिलीटर जोड़ सकते हैं, तो आपके पास एक कस्टम आवंटक की क्षमता भी होनी चाहिए; मान लें कि यह इंटरफ़ेस को बहुत जटिल करेगा। – ipapadop

37

अंक के अलावा @deft_code द्वारा प्रस्तुत किया, एक और भी कमजोर एक:

  • आप weak_ptr रों कि सभी shared_ptr एक दिया वस्तु को रों के बाद रहते मृत्यु हो गई है का उपयोग करते हैं, तो यह वस्तु की स्मृति रहेंगे नियंत्रण ब्लॉक के साथ स्मृति में आखिरी कमजोर_प्टर मर जाता है। दूसरे शब्दों में वस्तु नष्ट हो जाती है लेकिन अंतिम weak_ptr नष्ट होने तक इसे हटाया नहीं जाता है।
+1

यदि आप 'make_shared' का उपयोग नहीं करते हैं तो यह भी मामला है। केवल अंतर यह है कि नियंत्रण ब्लॉक स्मृति के अलग आवंटित गांठ में होगा। –

+13

@ माइक: निश्चित रूप से नहीं - आमतौर पर, यदि ऑब्जेक्ट में कोई साझा_ptrs नहीं है, केवल weak_ptrs, तो ऑब्जेक्ट तुरंत हटा दिया जाता है। मुझे पता नहीं है कि नियंत्रण ब्लॉक बनी हुई है, मैं इसके लिए अपना शब्द ले जाऊंगा। Make_shared के साथ, नियंत्रण ब्लॉक और ऑब्जेक्ट एक आवंटन को सह-आदत देता है, इसलिए यदि उनमें से एक के लिए स्मृति बनी रहती है तो दोनों करते हैं (हालांकि मुझे लगता है कि वस्तु नष्ट हो गई है, बस स्मृति मुक्त नहीं हुई है?)। –

+3

एर, हाँ। माफ़ कीजिये। जब मैंने लिखा था तो मुझे अपना दूसरा दिमाग होना चाहिए था। –

14

http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/

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

+0

क्या यह आगे बढ़ने की उम्मीद है क्योंकि कंपेलरों की प्रगति होती है? – Catskul

7

मेकअप के साथ आप निर्दिष्ट नहीं कर सकते कि कैसे आवंटन और आयोजित वस्तु का आवंटन रद्द करने किया जाएगा साझा की है।

जब कि वांछित है, std::allocate_shared<T> बजाय का उपयोग करें:

std::vector<std::shared_ptr<std::string>> avec; 
std::allocator<std::string> aAllocator; 
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!")); 

ध्यान दें कि वेक्टर संभाजक के बारे में सूचित करने की आवश्यकता नहीं है!

एक कस्टम संभाजक बनाने के लिए, साथ ही, make_shared कारखाने पैटर्न साथ संगत नहीं है एक नज़र यहाँ https://stackoverflow.com/a/542339/1149664

8

है। इसका कारण यह है अपने कारखाने समारोह के भीतर make_shared करने के लिए कॉल जो बारी में कॉल new पुस्तकालय कोड, कॉल, जो यह करने के लिए उपयोग, नहीं है क्योंकि यह वर्ग के निजी निर्माता (रों) (निर्माता (रों फोन नहीं कर सकते हैं) होना चाहिए निजी हो, अगर आप कारखाने के पैटर्न का सही ढंग से अनुसरण करते हैं)।

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