मैंने सुना auto_ptr
है C ++ 11 में पदावनत किया जा रहा है। इसका क्या कारण है?
इसके अलावा मैं auto_ptr
और के बीच का अंतर जानना चाहूंगा shared_ptr
।
जवाबों:
के लिए प्रत्यक्ष प्रतिस्थापन auto_ptr
(या किसी एक के लिए निकटतम चीज) है unique_ptr
। जहाँ तक "समस्या" चला जाता है, यह बहुत आसान है: auto_ptr
जब यह सौंपा जाता है तो स्वामित्व स्थानांतरित करता है। unique_ptr
स्वामित्व भी स्थानांतरित करता है, लेकिन चाल शब्दार्थों के कोडीकरण और प्रतिद्वंद्विता संदर्भों के जादू के लिए धन्यवाद, यह स्वाभाविक रूप से बहुत अधिक कर सकता है। यह बाकी मानक पुस्तकालय के साथ "फिट" भी काफी बेहतर है (हालांकि, निष्पक्षता में, उनमें से कुछ को हमेशा की नकल की आवश्यकता के बजाय कदम शब्दार्थ को समायोजित करने के लिए बदलते पुस्तकालय के बाकी हिस्सों के लिए धन्यवाद है)।
नाम में परिवर्तन भी एक स्वागत योग्य है (IMO) - auto_ptr
यह वास्तव में आपको इसके बारे में ज्यादा नहीं बताता है कि यह क्या करने की कोशिश करता है, जबकि unique_ptr
जो प्रदान किया गया है उसका काफी उचित (यदि प्रतिकूल) विवरण है।
auto_ptr
नाम पर एक नोट : ऑटो स्वचालित चर के रूप में स्वचालित रूप से सुझाव देता है, और यह एक चीज को संदर्भित करता auto_ptr
है: ऐसा करें: प्रबंधित संसाधन को उसके विध्वंसक (जब यह दायरे से बाहर हो जाता है) को नष्ट कर दें।
auto_ptr
: open-std.org/jtc1/sc22/wg21/docs/papers/2005/…
std::sort
लिए एक विशेषज्ञता नहीं है unique_ptr
। इसके बजाय इसे कभी भी कॉपी न करने के लिए फिर से निर्दिष्ट किया गया था। तो auto_ptr
वास्तव में आधुनिक के साथ काम करता हैsort
। लेकिन C ++ 98/03 sort
यहाँ केवल एक उदाहरण एल्गोरिथ्म है: कोई भी जेनेरिक अल्गोरिद्म (std-supply या user-लिखा) जो मानता है कि कॉपी सिंटैक्स में कॉपी सिमेंटिक्स है, संभवत: एक रन-टाइम एरर होगा जिसका उपयोग किया जाता है auto_ptr
, क्योंकि auto_ptr
चुपचाप चलता है कॉपी सिंटैक्स के साथ । मुद्दा अभी की तुलना में बहुत बड़ा है sort
।
मुझे मौजूदा उत्तर बहुत अच्छे लगे, लेकिन बिंदुओं के पीओवी से। IMO, एक आदर्श उत्तर में उपयोगकर्ता / प्रोग्रामर का परिप्रेक्ष्य उत्तर होना चाहिए।
पहली बात पहले (जैसा कि उनके जवाब में जेरी कॉफ़िन ने बताया)
share_ptr: यदि आप संसाधन / मेमोरी को मुक्त करने के बारे में चिंतित हैं और यदि आपके पास एक से अधिक फ़ंक्शन हैं जो ऑब्जेक्ट AT-DIFFERENT समय का उपयोग कर सकते हैं, तो साझा करें_ptr के साथ।
DIFFERENT-Times द्वारा, ऐसी स्थिति के बारे में सोचें जहां ऑब्जेक्ट-ptr को कई डेटा-स्ट्रक्चर में संग्रहीत किया जाता है और बाद में एक्सेस किया जाता है। कई धागे, निश्चित रूप से एक और उदाहरण है।
unique_ptr: यदि आप सभी चिंतित हैं तो मेमोरी को खाली कर रहा है, और ऑब्जेक्ट तक पहुंच अनुक्रमिक है, तो unique_ptr पर जाएं।
SEQUENTIAL द्वारा, मेरा मतलब है, किसी भी बिंदु पर वस्तु को एक संदर्भ से एक्सेस किया जाएगा। उदा। एक ऐसी वस्तु जो सृष्टिकर्ता द्वारा निर्माण के तुरंत बाद बनाई और इस्तेमाल की गई थी। निर्माण के बाद ऑब्जेक्ट को FIRST डेटा-स्ट्रक्चर में संग्रहीत किया जाता है । तब या तो ऑब्जेक्ट डेटा-संरचना के बाद नष्ट हो जाता है या सेकंड डेटा-स्ट्रक्चर में चला जाता है ।
इस लाइन से, मैं स्मार्ट-पॉइंटर्स के रूप में साझा / अद्वितीय _ptr का उल्लेख करूंगा। (auto_ptr स्मार्ट-पॉइंटर BUT भी है क्योंकि इसमें डिज़ाइन की खामियां हैं, जिसके लिए उन्हें पदावनत किया जा रहा है, और जो मुझे लगता है कि मैं अगली पंक्तियों में इंगित करूँगा, उन्हें स्मार्ट-पॉइंटर के साथ समूहीकृत नहीं किया जाना चाहिए।)
Auto -ptr को स्मार्ट-पॉइंटर के पक्ष में पदावनत करने के लिए एकल सबसे महत्वपूर्ण कारण असाइनमेंट-शब्दार्थ है यदि यह इस कारण से नहीं था, तो उन्होंने इसे पदावनत करने के बजाय auto_ptr में कदम अर्थ के सभी नए उपहार जोड़े होंगे। चूंकि असाइनमेंट-शब्दार्थ सबसे अधिक नापसंद करने वाला फीचर था, वे चाहते थे कि यह सुविधा चली जाए, लेकिन चूंकि कोड लिखा हुआ है जो उस शब्दार्थ का उपयोग करता है, (जो मानक-समिति बदल नहीं सकते हैं), उन्हें auto_rr के बजाय जाने देना था इसे संशोधित कर रहा है।
लिंक से: http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
Unqiue_ptr द्वारा समर्थित असाइनमेंट की तरह
से: http://www.cplusplus.com/reference/memory/auto_ptr/operator=/
Auto_ptr द्वारा समर्थित असाइनमेंट की तरह
अब इस कारण से आकर कॉपी का असाइनमेंट अपने आप में कितना नापसंद था, मेरे पास यह सिद्धांत है:
अनपेक्षित व्यवहार वास्तव में नापसंद है और इसलिए auto_ptr के लिए नापसंद है।
(प्रोग्रामर्स के 3.1415926536% के लिए, जो जानबूझकर स्वामित्व को स्थानांतरित करना चाहते हैं C ++ 11 ने उन्हें std :: move () दिया, जिसने कोड को पढ़ने और बनाए रखने वाले सभी इंटर्न के लिए अपना इरादा क्रिस्टल स्पष्ट कर दिया।)
auto_ptr
एक ही वस्तु की ओर इशारा करते हुए दो मान नहीं चाहते हैं (चूंकि वे साझा स्वामित्व नहीं देते हैं, इसलिए मरने वाला पहला व्यक्ति दूसरे को एक घातक विरासत के साथ छोड़ देगा; यह unique_ptr
उपयोग के लिए भी सही है ), क्या आप सुझाव दे सकते हैं कि क्या इरादा था ; शेष 96.8584073465% सभी उपयोग?
*a=*b;
यहां केवल b की वैल्यू कॉपी की जाती है a। मुझे आशा है कि बी और बी दोनों का स्वामित्व अभी भी एक ही लोगों के पास है। आपने उल्लेख किया है कि ओवेरियनशिप को स्थानांतरित कर दिया जाएगा। ये कैसे होगा?
auto_ptr
ऑब्जेक्ट को स्वयं असाइन करने के बारे में बात कर रहा था । अपने इंगित किए गए मान से / पर असाइन करने का न तो स्वामित्व पर कोई प्रभाव पड़ता है, न ही प्रासंगिकता पर। मुझे आशा है कि आप अभी भी उपयोग नहीं कर रहे हैं auto_ptr
?
फिर भी एक और अंतर समझाने के लिए ले लो ...।
कार्यात्मक रूप से, C ++ 11 का std::unique_ptr
"निश्चित" हैstd::auto_ptr
: निष्पादन के दौरान किसी भी समय दोनों - उपयुक्त हैं - एक इंगित करने वाली वस्तु के लिए एक ही स्मार्ट-पॉइंटर मालिक होना चाहिए।
महत्वपूर्ण अंतर कॉपी-निर्माण या असाइनमेंट में एक और अन-एक्सपायरिंग स्मार्ट पॉइंटर से है, जो =>
नीचे दी गई लाइनों पर दिखाया गया है :
std::auto_ptr<T> ap(...);
std::auto_ptr<T> ap2(get_ap_to_T()); // take expiring ownership
=> std::auto_ptr<T> ap3(ap); // take un-expiring ownership ala ap3(ap.release());
ap->xyz; // oops... can still try to use ap, expecting it to be non-NULL
std::unique_ptr<T> up(...);
std::unique_ptr<T> up2(get_up_to_T()); // take expiring ownership
=> std::unique_ptr<T> up3(up); // COMPILE ERROR: can't take un-expiring ownership
=> std::unique_ptr<T> up4(std::move(up)); // EXPLICIT code allowed
=> std::unique_ptr<T> up4(up.release()); // EXPLICIT code allowed
ऊपर, ap3
चुपचाप "चोरी" के स्वामित्व *ap
, ap
सेट करने के लिए जा रहा है nullptr
, और समस्या यह है कि बहुत आसानी से हो सकता है, बिना प्रोग्रामर अपनी सुरक्षा के माध्यम से सोचा था।
उदाहरण के लिए, यदि class
/ a struct
का कोई std::auto_ptr
सदस्य है, तो एक उदाहरण की एक प्रति बना release
रहा है, उदाहरण के लिए कॉपी की जा रही पॉइंटर से पॉइंटर होगा : यह अजीब और खतरनाक रूप से भ्रमित करने वाला शब्दार्थ है क्योंकि आमतौर पर किसी चीज को कॉपी करने से वह संशोधित नहीं होता है। क्लास / स्ट्रक्चर ऑथर के लिए यह आसान है कि जब वे इन्वर्टर और स्टेट के बारे में तर्क दे तो पॉइंटर की रिलीज़ को नजरअंदाज कर दें, और परिणामतः गलती से स्मार्ट-पॉइंटर को डीरेल करने का प्रयास करें, या अभी भी इंगित डेटा के एक्सेस / स्वामित्व की उम्मीद नहीं की है।
Auto_ptr का उपयोग STL कंटेनरों में नहीं किया जा सकता क्योंकि इसमें एक कॉपी कंस्ट्रक्टर है जो कंटेनर CopyConstructible की आवश्यकताओं को पूरा नहीं करता है । unique_ptr एक कॉपी कंस्ट्रक्टर को लागू नहीं करता है, इसलिए कंटेनर वैकल्पिक तरीकों का उपयोग करते हैं। unique_ptr को कंटेनरों में उपयोग किया जा सकता है और यह साझा एल्गोरिथम की तुलना में std एल्गोरिदम के लिए तेज़ है।
#include <iostream>
#include <type_traits>
#include <vector>
#include <memory>
using namespace std;
int main() {
cout << boolalpha;
cout << "is_copy_constructible:" << endl;
cout << "auto_ptr: " << is_copy_constructible< auto_ptr<int> >::value << endl;
cout << "unique_ptr: " << is_copy_constructible< unique_ptr<int> >::value << endl;
cout << "shared_ptr: " << is_copy_constructible< shared_ptr<int> >::value << endl;
vector<int> i_v;
i_v.push_back(1);
cout << "i_v=" << i_v[0] << endl;
vector<int> i_v2=i_v;
cout << "i_v2=" << i_v2[0] << endl;
vector< unique_ptr<int> > u_v;
u_v.push_back(unique_ptr<int>(new int(2)));
cout << "u_v=" << *u_v[0] << endl;
//vector< unique_ptr<int> > u_v2=u_v; //will not compile, need is_copy_constructible == true
vector< unique_ptr<int> > u_v2 =std::move(u_v); // but can be moved
cout << "u_v2=" << *u_v2[0] << " length u_v: " <<u_v.size() << endl;
vector< shared_ptr<int> > s_v;
shared_ptr<int> s(new int(3));
s_v.push_back(s);
cout << "s_v=" << *s_v[0] << endl;
vector< shared_ptr<int> > s_v2=s_v;
cout << "s_v2=" << *s_v2[0] << endl;
vector< auto_ptr<int> > a_v; //USAGE ERROR
return 0;
}
>cxx test1.cpp -o test1
test1.cpp: In function âint main()â:
test1.cpp:33:11: warning: âauto_ptrâ is deprecated (declared at /apps/hermes/sw/gcc/gcc-4.8.5/include/c++/4.8.5/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
vector< auto_ptr<int> > a_v; //USAGE ERROR
^
>./test1
is_copy_constructible:
auto_ptr: false
unique_ptr: false
shared_ptr: true
i_v=1
i_v2=1
u_v=2
s_v=3
s_v2=3