2008-11-06 17 views
9

std::auto_ptr में auto_ptr को प्रतिस्थापित करना वीसी ++ 8 में टूट गया है (जो हम काम पर उपयोग करते हैं)। इसके साथ मेरा मुख्य पकड़ यह है कि यह auto_ptr<T> x = new T(); की अनुमति देता है, जो निश्चित रूप से गलती से करने के लिए सरल होने पर, भयानक दुर्घटनाओं की ओर जाता है।वीसी ++ 8

stackoverflow पर एक और सवाल यहाँ करने के लिए एक answer से

:

नोट दृश्य स्टूडियो 2005 में std :: auto_ptr के कार्यान्वयन बुरी तरह टूट गया है कि। http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98871 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842

मैं

  • boost::scoped_ptr, उपयोग करने के लिए संकेत है कि स्वामित्व पारित नहीं करना चाहिए के लिए चाहते हैं।
  • boost::shared_ptr, कंटेनरों और अन्य जगहों पर पॉइंटर्स के लिए जहां उनकी आवश्यकता होती है।
  • std::auto_ptr, पॉइंटर्स के लिए जो स्वामित्व पास/पास कर सकते हैं।

लेकिन std::auto_ptr के बाद से मेरे लिए टूटी हुई है, मुझे आश्चर्य है कि क्या सबसे अच्छा तरीका होगा:

  • नेट से कुछ के साथ std::auto_ptr बदलें। रानी शारोनी से इस this की तरह (अभी तक यह कोशिश नहीं की है)।
  • इसके बजाय boost::shared_ptr का उपयोग करें। निश्चित रूप से काम करेगा, हालांकि कुछ मामूली उपरांत होगा जो मुझे परवाह नहीं है। लेकिन मैं सूचक के इरादे को इंगित करने के लिए auto_ptr का उपयोग करना चाहता हूं। (इस दृष्टिकोण पर वोट के लिए this उत्तर देखें।)
  • मुझे अभ्यास में स्वामित्व पास करने की आवश्यकता नहीं होगी, इसलिए मुझे इसके बारे में चिंता नहीं करनी चाहिए।

अद्यतन: यहाँ मैं क्या किया है: मैं रानी Sharoni से ऊपर उल्लिखित auto_ptr कार्यान्वयन की नकल की। From here

class T 
{ 
public: 
    T() { 
     OutputDebugStringA("T\n"); 
    }; 
    ~T() { 
     OutputDebugStringA("~T\n"); 
    }; 
}; 

{ 
    fix::auto_ptr<T> x(new T); // This just works. 
} 
{ 
    fix::auto_ptr<T> x = (new T); // Doesn't compile. Great! 
} 
{ 
    fix::auto_ptr<T> x = fix::auto_ptr<T>(new T); // Transfer of ownership works also. 
} 
बेशक

संपूर्ण नहीं हैं और आप उन पर भरोसा नहीं करना चाहिए द्वारा इन परीक्षणों हैं:

कुछ मामूली परीक्षण किया। अपवाद सुरक्षित टेम्पलेटेड वर्ग को कार्यान्वित करना बालों का व्यवसाय है। कम से कम यह एक में निर्मित से बेहतर काम करता है।

नोट: मुझे नहीं पता कि मुझे कॉपीराइट के संबंध में अभी तक इस कार्यान्वयन का उपयोग करने की अनुमति है या नहीं। मैंने रानी को ईमेल किया है और मैं एक उत्तर का इंतजार कर रहा हूं। जब मैं और जानूं तो मैं इस पोस्ट को अपडेट करूंगा। हर किसी के लिए रानी शारोनी के auto_ptr कार्यान्वयन का उपयोग करने के लिए अनुमति दी जाती है जैसा आप चाहें।

आपके सभी उत्तरों के लिए धन्यवाद।

+0

पासिंग स्वामित्व कुछ ऐसा नहीं होता जो अक्सर होता है, लेकिन यह कोड के हिस्से के रूप में स्वयं दस्तावेज़ों का एक साफ तरीका प्रदान करता है। –

+0

यह बिल्कुल मेरा विचार है। मैं स्वयं दस्तावेज कोड की पूजा करता हूं। –

उत्तर

7

ले जाएँ।

इस बीच, आप पुराने/दूसरे एसटीएल से एक काम कर रहे auto_ptr कार्यान्वयन को निकालना चाहते हैं, इसलिए आपके पास कोडिंग कोड है।

मेरा मानना ​​है कि auto_ptr semantics मूल रूप से टूटा हुआ है - यह टाइपिंग बचाता है, लेकिन इंटरफ़ेस वास्तव में आसान नहीं है: आपको अभी भी ट्रैक करना होगा कि वर्तमान उदाहरण कौन सा उदाहरण है और यह सुनिश्चित कर लें कि मालिक आखिरी बार छोड़ देता है।

अद्वितीय-पीटीआर "फिक्सेस" कि रिलीज करके न केवल स्वामित्व छोड़ दें, बल्कि आरएचएस को शून्य में भी सेट करें। यह ऑटो-पीआरटी के लिए निकटतम प्रतिस्थापन है, लेकिन इसके विभिन्न अर्थशास्त्र के साथ यह ड्रॉप-इन प्रतिस्थापन नहीं है।

boost smart pointers पर एक प्रारंभिक लेख है, मेरे द्वारा, अहम।

+0

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

+0

एर, 'auto_ptr' भी किसी भी प्रतिलिपि पर आरएचएस को शून्य करने के लिए सेट करता है। इस तरह यह स्वामित्व देता है! –

+0

आईआईआरसी कुछ (या प्रारंभिक) कार्यान्वयन नहीं किया। – peterchen

0

बढ़ावा का उपयोग करें :: shared_ptr/boost :: scoped_ptr। आने वाले सी ++ मानकों में यह पसंदीदा स्मार्ट पॉइंटर होगा (पहले से ही टीआर 1 में है)।

संपादित करें: कृपया यहाँ एक संबंधित चर्चा पाते हैं: Idiomatic use of std::auto_ptr or only use shared_ptr?

+0

पसंदीदा एक मजबूत शब्द है। shared_ptr और auto_ptr अलग-अलग चीजें करते हैं। –

+0

हां, यह सच है: मैं आमतौर पर shared_ptr का उपयोग करता हूं, लेकिन यह इस तथ्य के कारण हो सकता है कि auto_ptr के लिए मेरे पास कभी भी कोई केस नहीं था। – MP24

+0

मैं पहले से ही स्टैक ओवरफ्लो पर स्मार्ट पॉइंटर के बारे में अन्य चर्चाओं का पालन कर रहा हूं, लेकिन आपको अभी भी धन्यवाद। मैं पहले से ही राय मान रहा हूं कि मैं ऑटो, साझा और स्कॉप्ड का उपयोग करना चाहता हूं। लेकिन मेरे कंपाइलर (और इसकी लाइब्रेरी कार्यान्वयन) के कारण, मुझे यकीन नहीं है कि क्या करना है। –

1

क्यों आपको लगता है std :: auto_ptr <> टूटे कर दिया जाए।

मुझे लगता है कि कुछ ऐसा बुरा होगा जैसा मानकों की समिति को सूचित किया गया होगा!

तुम्हारा मतलब है कि आप की जरूरत है:

std::auto_ptr<T> x(new T); // Use the explicit constructor. 
+0

यह हर जगह तोड़ नहीं है। बस विशेष रूप से वीसी ++ 8. वीसी ++ 9 में बेहतर कार्यान्वयन है। –

+2

हां। या तो std :: auto_ptr x (नया टी); या std :: auto_ptr x = std :: auto_ptr (नया टी); काम करेगा। std :: auto_ptr x = new टी; संकलित नहीं करना चाहिए। यह करता है और परिणाम अपरिभाषित है। –

+0

"परिणाम अपरिभाषित" से आपका क्या मतलब है? क्या यह सिर्फ कन्स्ट्रक्टर को स्पष्ट रूप से कॉल नहीं करना चाहिए? बेशक यह अभी भी (तर्कसंगत) एक दोष है। –

3

आप STLPort का उपयोग कर विचार किया है?

+0

वह 'auto_ptr कार्यान्वयन को बदलें' विचार के अनुरूप होगा। मुझे आशा है कि मैं अपने प्रोजेक्ट में एक नया एसटीएल कार्यान्वयन शुरू करने से कुछ कम कर सकता हूं। यह दो साल का है और हम इसे लिखने वाले पांच लोग हैं। लेकिन फिर भी धन्यवाद। –

+0

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

+0

मैं दूसरा हूं। एसटीएल को प्रतिस्थापित करना एसटीएलपोर्ट का उपयोग करने के लिए प्रोजेक्ट को कॉन्फ़िगर करने का एक साधारण मामला होना चाहिए (जो मुझे लगता है कि मूल एसटीएल का उपयोग किया जाता है, यह टूटा नहीं जाता है)। –

2

एक अद्वितीय_ptr का उपयोग करें। मुझे लगता है कि ये एक बेहतर auto_ptr होने के लिए पेश किए गए थे।

http://www.boost.org/doc/libs/1_35_0/doc/html/interprocess/interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.unique_ptr

वास्तव में, मुझे विश्वास है auto_ptr यह के पक्ष में पदावनत किया जा सकता है का नेतृत्व कर रहा हूँ: स्मार्ट संकेत बढ़ावा देने के लिए

http://objectmix.com/c/113487-std-auto_ptr-deprecated.html

+0

बूस्ट में एक उपलब्ध है, हालांकि मुझे 100% यकीन नहीं है कि वीसी के कौन से संस्करणों में पर्याप्त भाषा मानक अनुरूपता है जो इसका समर्थन करने में सक्षम है। –

+0

इसके अलावा, केवल एक बढ़ावा क्यों है :: इंटरप्रोसेस :: unique_ptr और कोई बढ़ावा नहीं :: unique_ptr। मैं इस पथ को लेने से पहले और जानना चाहता हूं। अद्वितीय_ptr के लिए मानक प्रस्ताव केवल मानक मानक नए कंपेलरों (जीसीसी) पर काम करते हैं। –

+0

इसके अलावा, मुझे लगता है कि auto_ptr को बहिष्कृत करना केवल प्रासंगिक होगा जब इसे unique_ptr द्वारा प्रतिस्थापित किया जाता है। –

0

जहाँ तक मुझे याद है, यह नहीं था:

auto_ptr<T> x = auto_ptr<T>(new T()); ?? 
+1

यह काफी लंबा है - 'auto_ptr x (नया टी())' कम चौराहे के रास्ते में ऐसा ही करेगा। –

0

नहीं एक जवाब है, लेकिन किसी को भी, जिनके लिए इन कीड़े प्रासंगिक हैं के सामान्य हित के लिए। वीसी 8 के auto_ptr के साथ one more related bug है, जिसे अंतर्निहित अपवादों के साथ करना है। यह शायद गुच्छा का सबसे बुराई है, क्योंकि अन्य बग आपको कोड को संकलित करने देते हैं जो बिना किसी विफलता के मानक के अनुसार अवैध है, लेकिन कम से कम अनुपालन कोड ठीक काम करता है। इस बग के साथ, वास्तव में अनुपालन कोड सही ढंग से काम नहीं करता है।

समस्या यह है। मानक auto_ptr कन्स्ट्रक्टर और रूपांतरण ऑपरेटर इस तरह से निर्दिष्ट करता है कि वे सामान्य पॉइंटर्स के साथ auto_ptr एस के अंतर्निहित उत्थान का समर्थन करते हैं। हालांकि, इसके वीसी 8 कार्यान्वयन के बजाय reinterpret_cast करता है। स्वाभाविक रूप से, न केवल यह यू.बी. है। मानक के पत्र से, लेकिन यह कई आधार वर्गों और/या आभासी विरासत के साथ भी टूट जाता है।

struct Base1 { int x; }; 
struct Base2 { int y; }; 
struct Derived : Base1, Base2 {}; 

std::auto_ptr<Derived> createDerived() 
{ 
    return std::auto_ptr<Derived>(new Derived); 
} 

std::auto_ptr<Base2> base2(createDerived()); 

मेरे अतीत नौकरियों में से एक है, जब हम बस हेडर पैचिंग खुद (यह एक छोटी सी 2 लाइन ठीक है) उत्पादन, हम समाप्त हो गया में इस समस्या का सामना किया पर: यहाँ इस से टूट कानूनी कोड का एक उदाहरण है ।

संबंधित मुद्दे