std :: auto_ptr से std :: unique_ptr


185

नए मानक आने के साथ (और कुछ कंपाइलरों में पहले से मौजूद पार्ट्स), नए प्रकार के std::unique_ptrलिए एक प्रतिस्थापन माना जाता है std::auto_ptr

क्या उनका उपयोग वास्तव में ओवरलैप होता है (इसलिए मैं अपने कोड पर एक वैश्विक खोज / प्रतिस्थापन कर सकता हूं (यह नहीं कि मैं ऐसा करूंगा, लेकिन अगर मैंने किया है) या क्या मुझे कुछ अंतरों के बारे में पता होना चाहिए जो दस्तावेज़ पढ़ने से स्पष्ट नहीं हैं?

इसके अलावा, अगर यह एक प्रत्यक्ष प्रतिस्थापन है, तो इसे सुधारने के बजाय एक नया नाम क्यों दें std::auto_ptr?

जवाबों:


219

आप एक वैश्विक खोज / प्रतिस्थापित नहीं कर सकते क्योंकि आप एक auto_ptr(ज्ञात परिणामों के साथ) की प्रतिलिपि बना सकते हैं , लेकिन unique_ptrइसे केवल स्थानांतरित किया जा सकता है। जो कुछ भी दिखता है

std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p; 

कम से कम इस तरह बनना होगा

std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);

अन्य अंतरों के लिए, unique_ptrसरणियों को सही ढंग से संभाल सकता है (यह कॉल करेगा delete[], जबकि auto_ptrकॉल करने का प्रयास करेगा delete


101
दूसरी ओर, इस खोज / प्रतिस्थापन को करने से केवल संकलन त्रुटियां होंगी, यह चुपचाप कोड को नहीं तोड़ देगा जहां तक ​​मैं देख सकता हूं। इसलिए यह करना सुरक्षित है, यदि आप मैन्युअल रूप से संकलित त्रुटियों को बाद में ठीक करते हैं
jalf

7
@ जैलफ: वास्तव में, मैं एक काउंटर-उदाहरण के बारे में नहीं सोच सकता हूं जो कि ऑटो_प्टर्स और यूबी के साथ यूनिक_प्टर्स के साथ अच्छी तरह से परिभाषित होगा।
क्यूबाई

1
तो ऐसा लगता है जैसे कि unique_ptr auto_ptr की वृद्धि है: समर्थन सरणी और अस्पष्टता को दूर करें
ब्यान हुआंग

92

std::auto_ptrऔर std::unique_ptrकिसी में असंगत हैं और दूसरों में प्रतिस्थापन में गिरावट है। इसलिए, कोई खोज / प्रतिस्थापन पर्याप्त रूप से अच्छा नहीं है। हालाँकि, संकलन त्रुटियों के माध्यम से काम खोजने / बदलने के बाद अजीब कोने के मामलों को छोड़कर सब कुछ ठीक करना चाहिए। संकलित त्रुटियों में से अधिकांश को जोड़ने की आवश्यकता होगी std::move

  • फंक्शन स्कोप वैरिएबल:
    100% संगत, जब तक आप इसे दूसरे फ़ंक्शन के लिए मान से पास नहीं करते।
  • रिटर्न प्रकार:
    100% संगत नहीं है, लेकिन 99% संगत गलत नहीं लगता है।
  • मूल्य द्वारा फ़ंक्शन पैरामीटर:
    एक कैविटी के साथ 100% संगत, unique_ptrएक std::moveकॉल के माध्यम से पारित किया जाना चाहिए । यह एक सरल है क्योंकि कंपाइलर शिकायत करेगा यदि आप इसे सही नहीं करते हैं।
  • संदर्भ द्वारा फ़ंक्शन पैरामीटर:
    100% संगत।
  • वर्ग सदस्य चर:
    यह एक मुश्किल है। std::auto_ptrएस कॉपी शब्दार्थ बुराई हैं। यदि वर्ग नकल std::unique_ptrकरना छोड़ देता है तो प्रतिस्थापन में गिरावट आती है। हालाँकि, यदि आपने कक्षा को उचित कॉपी शब्दार्थ देने की कोशिश की है, तो आपको std::auto_ptrहैंडलिंग कोड को बदलना होगा । यह सरल है क्योंकि कंपाइलर आपको सही नहीं मिलने पर शिकायत करेगा। यदि आपने किसी विशेष कोड के बिना किसी std::auto_ptrसदस्य के साथ कक्षा की नकल करने की अनुमति दी है , तो आप पर शर्म और शुभकामनाएं।

संक्षेप में, std::unique_ptrएक अखंड है std::auto_ptr। यह संकलन समय व्यवहारों को अस्वीकार करता है जो अक्सर उपयोग करते समय त्रुटियां थीं std::auto_ptr। इसलिए यदि आप std::auto_ptrइसकी आवश्यकता के साथ उपयोग करते हैं, तो स्विचिंग std::unique_ptrसरल होना चाहिए। यदि आप std::auto_ptrअजीब व्यवहार पर भरोसा करते हैं, तो आपको वैसे भी अपने कोड को फिर से भरने की आवश्यकता है।


8
+1 के लिए "आपको अपने कोड को वैसे भी रीफ़्रैक्टर करने की आवश्यकता है"। auto_ptrs केवल 20.4.5 / 3 के लिए अच्छे हैं, वे कहते हैं कि वे अच्छे हैं।
क्यूबाई

8
मुझे इसमें यह जोड़ना चाहिए कि आपको अपने कोड में auto_ptr को unique_ptr से बदलकर संकलन त्रुटियों को ठीक करना चाहिए। आपको आश्चर्य होगा कि यह कितने कीड़े को उजागर करेगा।
बार्टोज़ मिल्वाइस्की

36

AFAIK, unique_ptrप्रत्यक्ष प्रतिस्थापन नहीं है। इसे ठीक करने वाला प्रमुख दोष स्वामित्व का अंतर्निहित हस्तांतरण है।

std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership

std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly

दूसरी ओर, unique_ptrपूरी तरह से नई क्षमताएं होंगी: उन्हें कंटेनरों में संग्रहीत किया जा सकता है।


8
स्कॉट मेयर्स ने अपने "इफेक्टिव सी ++" (तीसरे संस्करण) आइटम 13 (पेज 64) में भी उल्लेख किया है कि एसटीएल कंटेनरों के लिए आवश्यक है कि उनकी सामग्री "सामान्य" नकल वाले व्यवहार को प्रदर्शित करे, इसलिए कंटेनरों की auto_ptrअनुमति नहीं है।
Qiang जू

31

हर्ब सटर ने GotW # 89 पर एक अच्छी व्याख्या की है :

Auto_ptr के साथ क्या हुआ है? ऑटोलिफ्ट को सी + + स्थानांतरित करने से पहले एक अनूठे तरीके से एक अनूठे प्रयास के रूप में सबसे स्पष्ट रूप से चित्रित किया गया है। auto_ptr अब पदावनत हो गया है, और इसका उपयोग नए कोड में नहीं किया जाना चाहिए।

यदि आपके पास किसी मौजूदा कोड बेस में auto_ptr है, जब आपको एक वैश्विक खोज करने का प्रयास करने का मौका मिलता है और auto_ptr की जगह unique_ptr; उपयोग के विशाल बहुमत एक ही काम करेंगे, और यह उजागर हो सकता है (एक संकलन-समय त्रुटि के रूप में) या एक बग या दो (आप चुपचाप) ठीक करें जो आपको नहीं पता था कि आपके पास था।

दूसरे शब्दों में, जबकि एक वैश्विक खोज-और-जगह अस्थायी रूप से आपके कोड को "तोड़" सकती है, आपको इसे वैसे भी करना चाहिए: संकलन त्रुटियों को ठीक करने में कुछ समय लग सकता है, लेकिन लंबे समय में आपको बहुत अधिक परेशानी से बचाएगा।


बढ़िया लिंक। आपका बहुत बहुत धन्यवाद!
fotNelton
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.