2013-08-01 6 views
6

संभवतः नहीं।क्या एक पॉइंटर वैकल्पिक रूप से एक कॉन्स खाली कक्षा या गैर-कॉन्स क्लास को इंगित कर सकता है?

मैं दो वर्गों एक & बी

class A 
{ 
    B *b_; 
};   

class B 
{ 
public: 
    B(): b_string_("") {}; 

private:  
    std::string b_string_; 
}; 

मैं हमेशा के लिए b_ चाहते एक बी वस्तु को इंगित किया है: यहाँ मेरी उपयोग है। मैं b_ को nullptr के बजाय "खाली" बी ऑब्जेक्ट को इंगित करना चाहता हूं ताकि मैं खाली बी _-> b_string प्राप्त करने के लिए हमेशा परिभाषित तरीके से * b_ को अव्यवस्थित कर सकूं। तो मैंने सोचा कि मैं एक वैश्विक "नल बी ऑब्जेक्ट" बनाउंगा: const B null_b। लेकिन मैं इस स्वामित्व का उपयोग नहीं कर सकता (स्वाभाविक रूप से):

A(): b_(&null_b) {}; 

क्योंकि b_ किसी कॉन्स्ट चर को इंगित नहीं कर सकता है। यदि "नल बी ऑब्जेक्ट" नहीं है, तो बी_ को म्यूटेबल बी ऑब्जेक्ट्स को इंगित करने की आवश्यकता है।

वैश्विक गैर-कॉन्स समस्या को हल करता है लेकिन मुझे कॉन्स की सुरक्षा चाहिए ताकि मैं "शून्य ऑब्जेक्ट" कभी भी परिवर्तन न कर सकूं।

एफडब्ल्यूआईडब्ल्यू, इसमें एक बड़ी परियोजना शामिल है जहां बी_ किसी अन्य वर्ग में बी ऑब्जेक्ट्स के वेक्टर को इंगित कर रहा है। मैं उस वेक्टर में एक खाली बी ऑब्जेक्ट जोड़ सकता था लेकिन यह मुझे क्लूडी के रूप में मारता है।

क्या मेरी समस्या का समाधान करने के लिए कोई तरीका या पैटर्न है?

+1

मुझे शायद यह सुझाव नहीं देना चाहिए ... const_cast? – Borgleader

+0

क्या आप फ्लाईवेट की तलाश में हैं? लेकिन, ध्यान रखें कि सभी पॉइंटर्स तार्किक रूप से – sehe

+0

@ बॉर्गलीडर होंगे जो इससे यहां कैसे मदद करेंगे? आप रनटाइम पर पॉइंटर को कॉन्स्टेबल करने का निर्णय नहीं ले सकते हैं (यदि यह आपके नील ऑब्जेक्ट को इंगित करता है) – sehe

उत्तर

5

B ऑब्जेक्ट पर पॉइंटर रखने के बजाय वर्चुअल विधियों और स्टोर पॉइंटर्स के साथ बेस क्लास बनाएं। अपने B कक्षा और Null_B कक्षा दोनों को प्राप्त करें, लेकिन Null_B पर विधियों को संशोधित न करें। अब भी आपकी Null_B ऑब्जेक्ट const नहीं होगी, इससे कोई फर्क नहीं पड़ता।

सुरक्षा की एक अतिरिक्त परत के रूप में आप null_b ऑब्जेक्ट को अपवाद फेंकने का कोई प्रयास कर सकते हैं ताकि आप अपनी तर्क त्रुटि का पता लगा सकें और ढूंढ सकें।

+1

एक कामकाजी उदाहरण (सिवाय इसके कि Null_B सीधे बी से निकलता है) यहां: https://ideone.com/m5ezfh – Bill

+0

@ बिल और मार्क्रांसॉम - धन्यवाद जो काम करने जा रहा है। कोड बिल के लिए धन्यवाद! यह तुरंत तुरंत स्पष्ट कर दिया। :) –

1

अच्छा, शायद यह पूरी तरह से बिंदु से बाहर है, लेकिन ... क्या आप ए के अंदर बी के सूचक के बजाय बी के उदाहरण का उपयोग कर सकते हैं? यह संभावित nullptr dereferencing हल करेगा।

संपादित अच्छी तरह से, अगर B बहुत बड़ा है, तो आप इसके चारों ओर एक हल्के आवरण, और ए के अंदर है कि आवरण की दुकान उदाहरण आवरण आप कुछ सार्थक प्रदान करेगा अगर B nullptr है बना सकते हैं।

+0

नहीं - मुझे असली परियोजना में इस जटिल संरचना को इंगित करना है। न केवल मैं प्रतिलिपि बनाने के ऊपरी हिस्से को चाहता हूं, मुझे इसे अद्यतन करने की आवश्यकता है, न कि प्रतिलिपि। –

+0

आपकी मदद के लिए धन्यवाद! मुझे लगता है कि संक्षेप में मार्क और बिल का समाधान शून्य वस्तु के चारों ओर एक छोटा और मीठा रैपर था जिसे आप सुझाव दे रहे थे। –

3

आपके पास const ऑब्जेक्ट पर "गैर-कॉन्स्ट" पॉइंटर पॉइंट नहीं हो सकता है। और दुर्भाग्य से, const-ऑब्जेक्ट की समस्या को हटाने के लिए const_cast का उपयोग करने का अर्थ यह होगा कि कुछ कोड बाद में ऑब्जेक्ट को संशोधित करने का प्रयास कर सकते हैं। (ध्यान दें कि const को दूर करने के लिए यह अनिर्धारित व्यवहार है जब तक कि मूल वस्तु गैर-स्थिर न हो, इसलिए तकनीकी रूप से, संकलक को कोड उत्पन्न होने की अनुमति दी जाती है जो ऐसा होता है। दुर्भाग्यवश, कई मामलों में, जब ऑब्जेक्ट कुछ होता है तो यह क्रैश नहीं होगा const char * या const int [] से अधिक जटिल - कोड को आपके ऑब्जेक्ट को ओवरराइट करने के बाद खुशी से जारी रखने की अनुमति देता है जिसे आप लिखना नहीं चाहते थे)।

हालांकि, बाद से B वर्ग एक b_string_ सदस्य है कि निजी है, कोई बाहर वस्तु यह, छू सकता है ताकि आप सुनिश्चित कर सकते हैं कि b_string_ के किसी भी उपयोग के लिए एक आभासी समारोह (या एकाधिक आभासी कार्यों) के माध्यम से किया जाता है, फिर एक और निकाले जाते हैं B से कक्षा जहां, और वर्चुअल फ़ंक्शन "क्षमा करें, आप ऐसा नहीं कर सकते" जब कोड व्युत्पन्न ऑब्जेक्ट में b_string को संशोधित करने का प्रयास करता है।

+0

const_cast पहले स्थान पर यूबी है, जब तक कि आपको पता न हो कि पॉइंटी वास्तव में परिवर्तनीय है – sehe

+0

हां, मेरा मुद्दा यह था कि यदि आप दृढ़ता को दूर करते हैं, तो यह किसी को इसे संशोधित करने से नहीं रोकता है - यह यूबी होने के बावजूद है उस चरण पर इंगित करें, क्योंकि इसे 'कॉन्स्ट' बनाने का कारण संभवतः आप इसे संशोधित नहीं करना चाहते हैं - और अधिकांश प्रणालियों में औसत दिया गया है, यह शायद दुर्घटनाग्रस्त नहीं होगा, इसलिए यह खुशी से वस्तु के साथ काम करेगा सुलभ और अजीब चीजें हो रही हैं। –

+1

इसे संशोधित करना एप्लिकेशन को बहुत क्रैश कर सकता है। असल में यह ठीक होता है जब आप ** [औसत हैलो-वर्ल्ड लेवल ऐप में 'कॉन्स्ट char * 'के माध्यम से लिखें] (http://ideone.com/30zoCA) **। मुझे लगता है कि मेरा मुद्दा है "यूबी बिंदु के बगल में कभी नहीं है" – sehe

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