मानक कंटेनरों के साथ std :: auto_ptr <> का उपयोग करना क्यों गलत है?


217

std::auto_ptr<>मानक कंटेनरों के साथ उपयोग करना गलत क्यों है ?


5
निश्चित रूप से इस पर एक +1 क्योंकि मैंने देखा है कि बहुत से लोगों को यह गलत लगता है। यह बहुत अच्छा सवाल है।
20

कृपया संबंधित आइटम भी पढ़ें। यह प्रश्न दूसरी तरफ से यहां माना जाता है। Auto_ptr और STL कंटेनरों के बारे में और अधिक समझने में मददगार हो सकता है। stackoverflow.com/questions/8630552/…
निकोले


1
moveसिमेंटिक और unique_ptrसे संबंधित समस्याओं से बचने के लिए डिज़ाइन किए गए थे auto_ptr। C ++ 03 में, भाषा इतनी शक्तिशाली नहीं थी auto_ptrकि वह वर्ग लिख सके जैसे कि कंपाइलर के रूप में सभी परिदृश्यों में सही और सुरक्षित व्यवहार करता है और भाषा एल और आर के मूल्यों को भेदने में सक्षम नहीं थी, इसलिए कुछ "हैक" का उपयोग वांछित व्यवहार प्राप्त करने के लिए किया गया था। सर्वाधिक समय।
फिल 1970

अच्छा लेख: एसटीएल कंटेनर और ऑटो_प्रेटर्स - वे मिक्स क्यों नहीं करते हैं quantstart.com/articles/…
alfC

जवाबों:


124

C ++ मानक कहता है कि एक STL तत्व "कॉपी-कंस्ट्रक्टेबल" और "असाइन करने योग्य" होना चाहिए। दूसरे शब्दों में, एक तत्व को असाइन या कॉपी करने में सक्षम होना चाहिए और दो तत्व तार्किक रूप से स्वतंत्र हैं। std::auto_ptrइस आवश्यकता को पूरा नहीं करता है।

उदाहरण के लिए इस कोड को लें:

class X
{
};

std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);

std::auto_ptr<X> pX = vecX[0];  // vecX[0] is assigned NULL.

इस सीमा को पार करने के लिए, आपको C ++ 11 न होने पर std::unique_ptr, std::shared_ptrया std::weak_ptrस्मार्ट पॉइंटर्स या बूस्ट समकक्षों का उपयोग करना चाहिए । यहाँ इन स्मार्ट पॉइंटर्स के लिए बूस्ट लाइब्रेरी डॉक्यूमेंटेशन है।


7
यदि आपको साझा स्वामित्व की आवश्यकता नहीं है, तो आपको बूस्ट पॉइंटर कंटेनरों पर भी विचार करना चाहिए।
16:22

4
unique_ptrनकल को भी अस्वीकार कर देता है, इसलिए कुछ एसटीएल संचालन सही ढंग से काम नहीं करेंगे जब तक कि वे इसके चाल शब्दार्थ का उपयोग नहीं कर सकते।
माइक वेलर

4
"इस सीमा को पार करने के लिए, आपको इसका उपयोग करना चाहिए std::unique_ptr": वह वर्ग टेम्पलेट केवल चालित शब्दार्थ के कारण मौजूद हो सकता है (इसके विनिर्देशन के लिए संदर्भों की आवश्यकता होती है), इसलिए इसे मौलिक रूप से C ++ 11 की आवश्यकता होती है। हालाँकि (और संबंधित) C ++ 11 मानक अब यह नहीं कहता है कि एक एसटीएल तत्व प्रकार "कॉपी-कंस्ट्रक्टेबल" और "असाइन करने योग्य" होना चाहिए; मूव-कंस्ट्रक्टिव और मूव-असाइन करने योग्य पर्याप्तता। वास्तव में unique_ptrउदाहरण केवल चल-निर्माण योग्य और चाल-असाइन करने योग्य होते हैं। लेकिन auto_ptrउदाहरण हैं! परिणामस्वरूप, C ++ 11 में आप auto_ptrजो कर सकते हैं उसके साथ कर सकते हैं unique_ptr
मार्क वैन लीउवेन

जब तक आप resetऔर releaseजरूरत के रूप में @MarcvanLeeuwen
शाफ़्ट

2
@ratchetfreak: हम्म, मुझे समझ नहीं आया। क्या? "जब तक आप resetऔर release", मैं नहीं देखता कि मेरी टिप्पणी में कुछ भी कैसे लागू होता है। ध्यान दें कि दोनों के पास auto_ptrऔर unique_ptrदोनों तरीके हैं, और वे दोनों मामलों में एक ही काम करते हैं।
मार्क वैन लीउवेन

66

प्रतिलिपि अर्थ विज्ञान के auto_ptrकंटेनर के साथ संगत नहीं हैं।

विशेष रूप से, एक auto_ptrको दूसरे की नकल करना दो समान वस्तुओं का निर्माण नहीं करता है क्योंकि एक ने सूचक के स्वामित्व को खो दिया है।

अधिक विशेष रूप से, auto_ptrपॉइंटर को जाने देने के लिए प्रतियों में से एक को कॉपी करता है । कंटेनर में इनमें से कौन सा अवशेष परिभाषित नहीं है। इसलिए, यदि आप auto_ptrsकंटेनरों में स्टोर करते हैं, तो आप बेतरतीब ढंग से पॉइंटर्स तक पहुंच खो सकते हैं ।


39

क्योंकि मुझे लगता है कि लगभग दो साल के अंतराल में, वह शायद हाथ में समस्या से निपटे।
पपी

27
@ डीडीएमजी: हाँ, आप सही हैं। लेकिन वह मेरा उद्देश्य नहीं था। अगर कोई इस थ्रेड में कुछ समय के लिए आता है और इसके बारे में auto_ptrऔर सामान सीखना चाहता है , तो ये लिंक सहायक होंगे, मुझे यकीन है।
लेज़र

हाल ही में बहुत सारे डुप्लिकेट हैं।
पिल्ला

8
@DeadMG: यह प्रश्न डुप्लिकेट के रूप में बंद नहीं किया गया था और इसलिए विस्तार के लिए खुला है। लेज़र ने कहा कि यहाँ से पहले क्या नहीं कहा गया था। मुझे लगता है कि वह संयोग से आया था।
सेबेस्टियन मच

दूसरे लिंक में स्पष्टीकरण, जो कॉल करने के बाद समस्या का विश्लेषण करते sort()हैं, यहां सभी उत्तरों की तुलना में स्पष्ट हैं।
चोसिंक

17

एसटीएल कंटेनरों को आपके द्वारा संग्रहित वस्तुओं को कॉपी करने में सक्षम होना चाहिए, और मूल और कॉपी के समकक्ष होने की उम्मीद करने के लिए डिज़ाइन किया गया है। ऑटो पॉइंटर ऑब्जेक्ट का एक पूरी तरह से अलग अनुबंध होता है, जिससे नकल स्वामित्व का हस्तांतरण होता है। इसका मतलब यह है कि auto_ptr के कंटेनर उपयोग के आधार पर अजीब व्यवहार प्रदर्शित करेंगे।

प्रभावी एसटीएल (स्कॉट मेयर्स) आइटम 8 में क्या गलत हो सकता है और प्रभावी सी ++ (स्कॉट मेयर्स) आइटम 13 में एक नहीं-तो-विस्तृत विवरण भी है।


12

एसटीएल कंटेनर निहित वस्तुओं की प्रतियां संग्रहीत करते हैं। जब एक auto_ptr कॉपी किया जाता है, तो यह पुराने ptr को शून्य में सेट करता है। इस व्यवहार से कई कंटेनर विधियाँ टूट जाती हैं।


लेकिन, जब यूनीक_प्ट्र का उपयोग करते हैं तो आपको एक ही चीज मिलती है क्योंकि केवल एक यूनिक_प्रेट वस्तु का स्वामित्व हो सकता है?
ट्रेसर

2
@Tracer unique_ptrकिसी भी उचित सी ++ 11 वस्तु केवल जब चाल-निर्माण या -assigned अपने संसाधन के स्वामित्व का हस्तांतरण कर सकते हैं, यह सुनिश्चित करना कि प्रोग्रामर जानबूझ कर एक से गुजरना होगा की तरह std::move(sourceObject), या एक अस्थायी बल्कि एक गुजर से lvalue अनिश्चित होने से उत्परिवर्तित और unintuitively / प्रतिलिपि-असाइनमेंट ... जो, जैसा कि यहां पूरी तरह से जोर दिया गया है, की एक मुख्य समस्या थी auto_ptr
अंडरस्कोर_ड

4

C ++ 03 मानक (ISO-IEC 14882-2003) खंड 20.4.5 पैरा 3 में कहता है:

[...] [ ध्यान दें: [...] auto_ptr मानक लाइब्रेरी कंटेनर तत्वों के लिए CopyConstructible और Assignable आवश्यकताओं को पूरा नहीं करता है और इस प्रकार एक अपरिचित व्यवहार में एक auto_ptr परिणामों के साथ एक मानक लाइब्रेरी कंटेनर को तत्काल बदल देता है। - अंतिम नोट ]

C ++ 11 स्टैंडर्ड (ISO-IEC 14882-2011) परिशिष्ट D.10.1 पैराग्राफ 3 में कहता है:

[...] नोट: [...] Auto_ptr के उदाहरण MoveConstructible और MoveAssignable की आवश्यकताओं को पूरा करते हैं, लेकिन CopyConstructible और CopyAssignable की आवश्यकताओं को पूरा नहीं करते हैं। - अंतिम नोट]

C ++ 14 स्टैंडर्ड (ISO-IEC 14882-2014) परिशिष्ट C.4.2 अनुलग्नक D में कहता है: संगतता सुविधाएँ:

परिवर्तित करें : वर्ग टेम्पलेट auto_ptr, unary_function और बाइनरी_फंक्शन, फ़ंक्शन टेम्पलेट random_shuffle, और फ़ंक्शन टेम्पलेट (और उनके वापसी प्रकार) ptr_fun, mem_fun, mem_fun.ref, bind1st और bind2nd परिभाषित नहीं हैं।
Rationale : नई सुविधाओं से घिरा हुआ।
मूल सुविधा पर प्रभाव : मान्य C ++ 2014 कोड जो इन क्लास टेम्प्लेट और फ़ंक्शन टेम्प्लेट का उपयोग करता है, इस अंतर्राष्ट्रीय मानक में संकलित करने में विफल हो सकता है।

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