क्या C ++ 11 unique_ptr और shared_ptr एक दूसरे के प्रकार को बदलने में सक्षम है?


101

क्या C ++ 11 मानक पुस्तकालय किसी std::shared_ptrको std::unique_ptr, या इसके विपरीत से परिवर्तित करने के लिए कोई उपयोगिता प्रदान करता है ? क्या यह सुरक्षित संचालन है?


कृपया "सुरक्षित संचालन" को परिभाषित करें। आप किस तरह की सुरक्षा की तलाश कर रहे हैं? आजीवन प्रबंधन सुरक्षा? धागा सुरक्षा?
— jaggedSpire

2
"एसटीएल" का मतलब मानक पुस्तकालय नहीं है। एसटीएल का कोई लेना-देना नहीं है shared_ptr।
— १५

1
@jaggedSpire थ्रेड सुरक्षा का मतलब होगा कि आपके पास विभिन्न थ्रेड्स में उपयोग किए जाने वाले स्वामी हैं, अर्थात उपयोग संख्या 1. नहीं है
— curiousguy

@curiousguy मुझे पता था कि। मेरी बात "सुरक्षा" ओपी के प्रश्न में अच्छी तरह से परिभाषित नहीं थी, और उन्हें यह स्पष्ट करने की आवश्यकता थी कि किस प्रकार की "सुरक्षा" का मतलब है कि वे कई प्रकार के हैं।
— jaggedSpire

जवाबों:


163

std::unique_ptrअनन्य स्वामित्व को व्यक्त करने का C ++ 11 तरीका है, लेकिन इसकी सबसे आकर्षक विशेषताओं में से एक यह है कि यह आसानी से और कुशलता से एक में परिवर्तित हो जाता है std::shared_ptr।

यह std::unique_ptrफैक्ट्री फ़ंक्शन रिटर्न प्रकार के रूप में इतनी अच्छी तरह से अनुकूल होने का एक महत्वपूर्ण हिस्सा है । फ़ैक्ट्री फ़ंक्शंस यह नहीं जान सकते हैं कि कॉल करने वाले ऑब्जेक्ट के लिए अनन्य स्वामित्व वाले शब्दार्थ का उपयोग करना चाहते हैं या नहीं, या साझा स्वामित्व (यानी std::shared_ptr) अधिक उपयुक्त होगा। ए वापस करके std::unique_ptr, कारखाने सबसे कुशल स्मार्ट पॉइंटर के साथ कॉलर्स प्रदान करते हैं, लेकिन वे कॉलर्स को इसकी अधिक लचीली सिबलिंग से बदलने में बाधा नहीं डालते हैं।

std::shared_ptrकरने के लिए std::unique_ptrअनुमति नहीं है। एक बार जब आप एक संसाधन पर जीवन भर के प्रबंधन को बदल देते हैं std::shared_ptr, तो आपके दिमाग में कोई बदलाव नहीं होता है। यहां तक ​​कि अगर संदर्भ संख्या एक है, तो आप std::unique_ptrइसे प्रबंधित करने, कहने, करने के लिए संसाधन के स्वामित्व को पुनः प्राप्त नहीं कर सकते ।

संदर्भ: प्रभावी आधुनिक सी ++। 42 विशिष्ट C ++ 11 और C ++ 14 के अपने उपयोग को बढ़ाने के लिए। स्कॉट मेयर्स।

संक्षेप में, आप आसानी से और कुशलता से एक में बदल सकते हैं std::unique_ptrकरने के लिए std::shared_ptr, लेकिन आप परिवर्तित नहीं कर सकते std::shared_ptrकरने के लिए std::unique_ptr।

उदाहरण के लिए:

std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);

या:

std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");

9
...आप इसे कैसे करते हो?
— जेक

4
@ जेक मैंने एक उदाहरण जोड़ा है
— रसायन 989

ध्यान रखें कि संकलक की अनुमति नहीं होने पर (कम से कम gcc नहीं) वास्तव में यदि आप गलती से (जैसे कि सदस्य चर के सूचक प्रकार को बदलकर) a को असाइन करते हैं तो (या चेतावनी भी) नहीं रोकेंगे । std::unique_ptrstd::shared_ptr
— स्टेफानक्यू

-8

अनूठे_ptr u_ptr को देखते हुए, share_ptr s_ptr बनाएं:

std::shared_ptr<whatever> s_ptr(u_ptr.release());

दूसरे रास्ते पर जाना अव्यवहारिक है।


29
यहाँ "सही" तरीका है:std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
— emlai

6
और यहाँ पांडित्य "सही" तरीका है:std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
— पॉलीवेरटेक्स

3
इसके बारे में क्या कम सुरक्षित है?
— nrr

7
@VioletGiraffe • मुझे लगता है कि पॉलीवर्टेक्स नई इनिशियलाइज़ेशन सूची सिंटैक्स का उपयोग करने की वकालत कर रहा है - जो मूक संकुचन से बचा जाता है और एक समान वाक्यविन्यास के साथ सदस्य इनिशियलाइज़ेशन को समायोजित करता है - एक अच्छी आदत के रूप में। एक का छह, दूसरे का आधा दर्जन?
— एलजय

8
@nmr यह असुरक्षित है क्योंकि आप खो सकते हैं Deleterके अंदर संग्रहितunique_ptr
— झांग Mingjie
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.