2009-08-15 19 views
15

operator<< ओवरलोडिंग पर toString() -स्टाइल विधि की नकल करने के लिए उपलब्ध जानकारी का एक टन है जो एक जटिल ऑब्जेक्ट को स्ट्रिंग में परिवर्तित करता है। मुझे में भी में दिलचस्पी है, जिसमें किसी ऑब्जेक्ट में स्ट्रिंग को deserialize करने के लिए उलटा, operator>> लागू किया गया है।सुरक्षित रूप से स्ट्रीम ऑपरेटर ओवरलोडिंग >>

STL स्रोत का निरीक्षण करके, मैं इकट्ठा कर लिया है कि:

istream &operator>>(istream &, Object &); 

प्रकार Object की एक वस्तु deserializing के लिए सही समारोह हस्ताक्षर होगा। दुर्भाग्यवश, मुझे इस बात को ठीक से कार्यान्वित करने के लिए नुकसान हुआ है - विशेष रूप से त्रुटियों को कैसे संभालना है:

  1. स्ट्रीम में अमान्य डेटा कैसे इंगित करें? अपवाद फेंको?
  2. स्ट्रीम में विकृत डेटा है तो स्ट्रीम को किस स्थिति में होना चाहिए?
  3. ऑपरेटर चेनिंग के संदर्भ को वापस करने से पहले किसी भी झंडे को रीसेट किया जाना चाहिए?

उत्तर

18
  1. धारा में अमान्य डेटा कैसे इंगित करने के लिए? अपवाद फेंको?

आपको fail बिट सेट करना चाहिए। यदि स्ट्रीम का उपयोगकर्ता अपवाद को अपनाना चाहता है, तो वह स्ट्रीम को कॉन्फ़िगर कर सकता है (istream::exceptions का उपयोग करके), और धारा तदनुसार फेंक देगी। मैं इसे इस तरह तो क्या करना होगा,

stream.setstate(ios_base::failbit); 
  1. क्या राज्य धारा में होना चाहिए, अगर वहाँ धारा में विकृत डेटा है?

विकृत डेटा के लिए जो प्रारूप को फिट नहीं करता है, जिसे आप पढ़ना चाहते हैं, आपको आमतौर पर fail बिट सेट करना चाहिए। आंतरिक धारा विशिष्ट त्रुटियों के लिए, bad बिट का उपयोग किया जाता है (जैसे, यदि स्ट्रीम से कोई बफर कनेक्ट नहीं है)।

  1. ऑपरेटर चेनिंग के संदर्भ को वापस करने से पहले किसी भी झंडे को रीसेट करना चाहिए?

मैंने ऐसी कोई बात नहीं सुनी है।


देखना हो धारा एक अच्छी स्थिति में है के लिए, आप istream::sentry वर्ग का उपयोग कर सकते हैं। स्ट्रीम का ऑब्जेक्ट बनाएं और true (यह कहने के लिए कि तुरंत व्हाइटस्पेस को छोड़ना न करें)। eof, fail या bad बिट सेट होने पर प्रेषण false का मूल्यांकन करेगा।

istream::sentry s(stream, true); 
if(!s) return stream; 
// now, go on extracting data... 
+1

यह भी सुनिश्चित करें कि आप कुछ भी करने का प्रयास करने से पहले 'विफल' बिट की जांच करें। यदि यह पहले से सेट है, तो बस स्ट्रीम वापस करें। – KTC

+1

सलाह के लिए धन्यवाद, विशेष रूप से अपवादों के बजाय 'विफल' बिट का उपयोग करना। असफल बिट को सेट करने के अलावा, क्या मुझे स्ट्रीम की सामग्री के बारे में कोई गारंटी देनी चाहिए? उदाहरण के लिए, यदि मैं 'विफल' बिट सेट करता हूं, तो क्या स्ट्रीम अपरिवर्तित होनी चाहिए? –

+0

यह अनिवार्य रूप से मैं क्या कहने जा रहा था, लेकिन आपने तेज़ी से जवाब दिया! मैं जोड़ूंगा कि मौजूदा कार्यान्वयन क्या है, यह देखकर सही उत्तर मिलता है, जो आप वर्णन कर रहे हैं। साथ ही, मैं ध्यान दूंगा कि विकृत डेटा जैसी कोई चीज़ नहीं है, इसे पढ़ने के लिए गलत प्रारूप के रूप में; उस स्थिति में, आप यह सुनिश्चित करना चाहते हैं कि चर अपरिवर्तित है, और (यदि आप असफल बिट सेट करते हैं और खराब बिट नहीं) तो स्ट्रीम से कोई भी वर्ण खो नहीं गया है। –

0

झंडे के लिए, मुझे नहीं पता कि कहीं कोई मानक है या नहीं, लेकिन उन्हें रीसेट करना एक अच्छा विचार है।IO State Savers

+0

मुझे नहीं लगता कि यह निकालने वालों में उपयोग किए जाने के लिए डिज़ाइन किया गया है लेकिन उपयोगकर्ता कोड द्वारा। – AProgrammer

+0

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

2

कुछ अतिरिक्त नोट्स:

बूस्ट कि के लिए स्वच्छ आरए II रैपर है

  • जब ऑपरेटर >> लागू करने, तो आप शायद bufstream का उपयोग करने और नहीं ऑपरेटर के अन्य भार के विचार करना चाहिए> >;

  • आपरेशन के दौरान उत्पन्न अपवाद failbit या badbit लिए अनुवाद किया जाना चाहिए (streambuf के सदस्यों के लिए इस्तेमाल किया वर्ग के आधार पर, फेंक सकती है);

  • राज्य की स्थापना फेंक सकता है; यदि आप अपवाद को पकड़ने के बाद राज्य सेट करते हैं, तो आपको मूल अपवाद का प्रचार करना चाहिए, न कि सेटस्टेट द्वारा फेंक दिया गया है;

  • चौड़ाई एक ऐसा क्षेत्र है जहां आपको ध्यान देना चाहिए। यदि आप खाते में ले रहे हैं, तो आपको इसे 0 पर रीसेट करना चाहिए। यदि आप मूल कार्य करने के लिए अन्य ऑपरेटर >> का उपयोग कर रहे हैं, तो आपको प्राप्त होने वाली चौड़ाई को से गुजरने वाली चौड़ाई की गणना करनी होगी;

  • लोकेल को ध्यान में रखने पर विचार करें।

लैंग और Kreft (स्टैंडर्ड सी ++ IOStreams और स्थानों) भी अधिक जानकारी के में बातचीत इस। वे त्रुटि प्रबंधन के लिए एक टेम्पलेट कोड देते हैं जो एक पृष्ठ के बारे में लेता है।

+0

आप अन्य अधिभारों के बजाय 'बस्ट्रीम' का उपयोग करने का सुझाव क्यों देते हैं (उदा।' आईट्रीम '? मैं लेंज और क्रेफ्ट के काम को देखना सुनिश्चित करूँगा - ऐसा लगता है कि मैं जो खोज रहा हूं। –

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