2012-07-27 12 views
11

क्या एक स्मार्ट पॉइंटर लिखना संभव है जो ऑब्जेक्ट को अपने कन्स्ट्रक्टर में आवंटित करता है - डेवलपर को new पर कॉल करने के बजाय? दूसरे शब्दों में, बजाय लिखने के लिए:एक स्मार्ट पॉइंटर अपने कन्स्ट्रक्टर में मेरे लिए नया() क्यों नहीं कॉल कर सकता है?

std::unique_ptr<myClass> my_ptr(new myClass(arg1, arg2))

... एक लिख सकते हैं:

std::smarter_ptr<myClass> my_ptr(arg1, arg2)

भाषा वाक्य रचना इस व्यक्त करने में सक्षम है? क्या यह वांछनीय होगा? घृणित? मैं इस गलती के खिलाफ की रक्षा करने के विशेष रूप से सोच रहा हूँ (अपने आप को जो मैं कर दिया है, निश्चित रूप से):

myFunction(std::unique_ptr<myClass>(new myClass()), std::unique_ptr<myClass>(new myClass()))

... जो लीक जोखिम जो भी वस्तु पहले आवंटित किया जाता है, तो दूसरा आवंटन होता है और फेंकता पहले ऑब्जेक्ट को अपने स्मार्ट पॉइंटर में सुरक्षित रूप से ensconced से पहले। लेकिन क्या एक बेहतर सूचक वास्तव में यह सुरक्षित बनाएगा?

+2

@ जो: यह एक चिंता है; जेनरेट कोड के लिए एक स्मार्ट पॉइंटर शुरू करने के परिणामस्वरूप उपयोग करने से पहले दो 'नए' अभिव्यक्तियों को निष्पादित करना काफी संभव है; अगर दूसरे फेंकता है तो आपको एक रिसाव मिलेगा। –

+2

@ जो: आप गलत हैं। 'tmp1 = नया myClass(); tmp2 = नया myClass(); arg1 = std :: unique_ptr (tmp1); arg2 = std :: unique_ptr (tmp2); MyFunction (arg1, arg2); 'एक पूरी तरह से कानूनी निष्पादन आदेश है। –

+1

काफी मेला, मैं खुद को गलत साबित करने की जांच कर रहा था। धन्यवाद। – Joe

उत्तर

17

make_shared() के कार्यान्वयन को देखें। यह एक नई वस्तु आवंटित करता है और इसमें से shared_ptr बनाता है।

+0

उत्कृष्ट - यह भी आवंटन बचाता है। धन्यवाद। :-) – bythescruff

2

यह सी ++ 11 के साथ नया संभव है जिसमें perfect forwarding और विविध टेम्पलेट जोड़े गए हैं।

2

यह वही समस्या है जो std::find और std::find_if की आवश्यकता है। आप new myClass(arg1) मामले में shared_ptr के मौजूदा सीटीआर से इस सीटीआर को अलग नहीं कर सकते हैं। तर्कों की संख्या बराबर है, और arg1 किसी भी प्रकार का हो सकता है।

इसलिए, आप एक और नाम की जरूरत है, और कहा कि make_shared

+0

यह टैग प्रकारों के साथ आसानी से सुलभ है, जैसे 'shared_ptr (std :: inplace_args, args ...)', जो कुछ भिन्न भिन्न कार्यों के लिए आवंटन तर्कों को पारित करने के लिए मानक भी करता है। – Xeo

+0

@Xeo, सच है, तो 'make_shared' आवश्यक नहीं है, यह ओपी सुझाव के रूप में किया जा सकता था, लेकिन' make_shared (तर्क ...) 'वैसे भी कम टाइपिंग है :) –

+0

@Xeo: दरअसल। कई संभावित समाधान हैं, और सी ++ पूरी तरह से संगत नहीं है। – MSalters

11

सामान्य तौर पर, यह एक स्मार्ट सूचक के निर्माता के साथ नहीं किया जा सकता है; स्मार्ट पॉइंटर को निष्क्रिय करने के लिए पॉइंटर तर्क का उपयोग किया जाना चाहिए, या एक नई वस्तु बनाने के लिए अग्रेषित किया जाना चाहिए या नहीं, इस पर एक अस्पष्टता होगी।

यह एक कारखाने समारोह के साथ किया जा सकता है, उदाहरण के लिए:

template <typename T, typename... Args> 
std::unique_ptr<T> make_unique(Args&&... args) { 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 

आप std::shared_ptr का उपयोग कर रहे हैं, तो आप std::make_shared उपयोग कर सकते हैं। यह केवल एक स्मृति आवंटन की आवश्यकता का लाभ देता है, जहां std::shared_ptr<T>(new T) को ऑब्जेक्ट के लिए एक और साझा संदर्भ गणना के लिए एक सेकंड की आवश्यकता होगी।

+0

निश्चित रूप से अस्पष्टता केवल तभी मौजूद होगी जब सुविधा मौजूदा स्मार्ट पॉइंटर्स में जोड़ दी गई हो, नहीं? मैं अभी भी उत्सुक हूं कि उन्हें 'make_shared() 'से शुरू करने के लिए क्यों लागू नहीं किया गया था; एक असमानता है जो मुझे स्मार्ट पॉइंटर कॉल 'डिलीट' करने में बग करता है लेकिन खुद को 'नया' कहता है। – bythescruff