2012-07-01 8 views
30

मेरे पुराने कोड परियोजनाओं के एक जोड़े जब मैं स्मार्ट संकेत कभी नहीं सुना था, जब भी मैं चाहे सूचक अभी भी एक मान्य वस्तु की ओर इशारा किया की जाँच करने के लिए आवश्यक में, मैं हमेशा करना होगा अगर कुछ इस तरह ...Nullptr और जाँच एक वैध वस्तु के लिए एक सूचक अंक

object * meh = new object; 
if(meh) 
    meh->member; 

या जब मैं इस

if(meh) 
{ 
    delete meh; 
    meh = 0; 
} 

खैर की तरह वस्तु को सुरक्षित रूप से कुछ को हटाने के लिए, की जरूरत है, अब मैं समस्याओं है कि वस्तुओं और संकेत का उपयोग करने से उत्पन्न हो सकता है के बारे में सीखा है बुलियन अभिव्यक्तियों में शाब्दिक संख्याओं के साथ, कठिन तरीका:। और अब मैं भी सी ++, nullptr कीवर्ड की तो कोई नई बात नहीं है, लेकिन बहुत अच्छा सुविधा के सीखा है। लेकिन अब मैं उत्सुक हूँ।

मैं पहले से ही के माध्यम से चला और मेरे कोड के सबसे संशोधित इतना है कि, उदाहरण के लिए, जब वस्तुओं को हटाने मैं अब लिखने

if(meh) 
{ 
    delete meh; 
    meh = nullptr; 
} 

अब मैं बूलियन के बारे में सोच रहा हूँ है। जब आप बस से पारित इस तरह एक अगर बयान में एक पूर्णांक कहते हैं,

int meh; 
if(meh) 

तो यह परोक्ष आप इसे लिखने के लिए जरूरत के बिना शून्य के लिए जाँच करता है।

if(meh == 0) // does the exact same check 

अब, सी ++ पॉइंटर्स के लिए समान होगा? यदि एक char * में इस तरह के बयान में पास हो?

char * meh; 
if(meh) 

तो क्या यह स्पष्ट रूप से इसकी तुलना नलप्टर से करेगा? कब तक मैं इस तरह इन आईएफएस लिख दिया है के कारण, यह जाँच करने के लिए इस बिंदु पर दूसरा स्वरूप है अगर संकेत टाइपिंग अगर (वस्तु *) और फिर अपने सदस्यों को फोन करके उपयोग करने से पहले मान्य। यदि यह कार्यक्षमता नहीं है तो क्यों नहीं? कार्यान्वित करना बहुत मुश्किल है? एक और छोटे तरीके को हटाकर आप कुछ समस्याएं हल कर सकते हैं जिससे आप अपना कोड गड़बड़ कर सकते हैं।

+22

आप ** हटाएं ** ** हटाए जाने से पहले पॉइंटर्स को किक करने की आवश्यकता नहीं है। 'Nullptr'' को हटाने के लिए यह पूरी तरह से सुरक्षित है। –

+1

आपके आखिरी उदाहरण में, क्या आपका मतलब 'char * meh = nullptr था; अगर (हुंह) '? सूचक अनियमित है। –

+3

आपकी 'नई' अभिव्यक्ति का नतीजा कभी भी शून्य नहीं होगा, अपवादों का उपयोग इसके बजाय किया जाता है। जैसा कि बताया गया है, शून्य को हटाना ठीक है, यह कुछ भी नहीं करता है। साथ ही, पॉइंटर्स मान को शून्य पर रीसेट न करना आम तौर पर बेहतर होता है। आखिरी बार इसका इस्तेमाल किया जाने वाला आखिरी बार होना चाहिए, इसलिए हटाए गए पॉइंटर तक पहुंच होने पर बग माना जाना चाहिए; इसे शून्य छिपाने के लिए सेट करें। – GManNickG

उत्तर

32

सी में, कुछ भी है कि 0 नहीं है सच है। तो, आप निश्चित रूप से उपयोग कर सकते हैं:

if (ptrToObject) 
    ptrToObject->doSomething(); 

सुरक्षित रूप से dereference पॉइंटर्स के लिए।

सी ++ 11 खेल को थोड़ा सा बदलता है, nullptr_t एक प्रकार है जिसमें nullptr एक उदाहरण है; nullptr_t का प्रतिनिधित्व कार्यान्वयन विशिष्ट है। तो एक संकलक nullptr_t परिभाषित कर सकता है हालांकि यह चाहता है। जिनमें से बूलियन अनुमति दी है - - यह केवल यकीन है कि यह विभिन्न प्रकार के एक nullptr_t की कास्टिंग पर उचित प्रतिबंध को लागू कर सकते हैं की जरूरत है और यकीन है कि यह एक nullptr_t और 0.

बीच भेद कर सकते तो nullptr हो जाएगा बनाने के ठीक से और परोक्ष करने के लिए डाली बूलियनfalse इतने लंबे समय के रूप में संकलक सी ++ 11 भाषा विवरण इस प्रकार। और उपरोक्त स्निपेट अभी भी काम करता है।

यदि आप एक संदर्भित वस्तु को हटाते हैं, तो कुछ भी नहीं बदलता है।

delete ptrToObject; 
assert(ptrToObject); 
ptrToObject = nullptr; 
assert(!ptrToObject); 

क्योंकि कितनी देर तक मैं इस तरह इन आईएफएस लिख दिया है की

, यह संकेत टाइप करके उपयोग करने से पहले वैध (वस्तु *) और फिर बुला अगर अगर जाँच करने के लिए इस बिंदु पर दूसरा स्वरूप है यह सदस्य है

सं (अधिमानतः अद्वितीय/स्मार्ट संकेत का प्रयोग करके) वस्तुओं की एक उचित ग्राफ बनाए रखने करें। जैसा कि बताया गया है, यह निर्धारित करने का कोई तरीका नहीं है कि कोई सूचक जो nullptr अंक मान्य ऑब्जेक्ट पर नहीं है या नहीं। वैसे भी जीवन चक्र को बनाए रखने के लिए आप पर निर्भर है .. यही कारण है कि पॉइंटर रैपर पहले स्थान पर मौजूद हैं।

+0

अच्छी तरह से मैं जानता था कि। जब तुलना के बिना छोड़ दिया जाता है, यदि बयानों की जांच करें कि क्या कुछ भी पारित किया गया है तो शाब्दिक कुछ भी हल हो जाता है। यदि int meh = 0 तो यह गलत साबित होता है। हालांकि अगर एक int * का पता 0x000 आदि का पता है जिसका अर्थ है कि यह किसी भी चीज़ पर इंगित नहीं करता है और बूल झूठी हल करेगा। अगर यह कहीं पर इंगित करता है, तो यह शून्य नहीं है और फिर यह सच हल करता है। लेकिन क्या होगा अगर आप पॉइंटर पर ऑब्जेक्ट हटा दें? पीआरटी स्टिल में 0x81A3 या कुछ पता है, लेकिन ऑब्जेक्ट चला गया है। आप अगर कॉल करते हैं, और यह सच हल करता है, भले ही वहां कोई ऑब्जेक्ट न हो। – FatalCatharsis

+1

जो रनटाइम त्रुटि का कारण बनता है, यदि आप पॉइंटर को शून्य करना भूल गए हैं। लेकिन अगर सूचक की तुलना नलप्टर के साथ पूरी तरह से की गई थी, तो क्या सूचक 0 था या कुछ संबोधित किया गया था, जब ऑब्जेक्ट वहां नहीं था तो यह गलत होगा। – FatalCatharsis

+2

हां। तो आपका सवाल क्या है? – dcow

6

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

तो meh एक कच्चे सूचक है तो if (meh) और if (meh != 0) और if (meh != nullptr) के बीच कोई अंतर नहीं है। वे सभी आगे बढ़ते हैं अगर सूचक शून्य नहीं है।

शाब्दिक 0 से nullptr पर एक अंतर्निहित रूपांतरण है।

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