2010-05-18 14 views
20

मेरा प्रश्न सरल है: सी ++ में शून्य पॉइंटर्स क्या हैं? (वे चीज़ें जिन्हें आप void* myptr; के साथ घोषित करते हैं)सी ++ में शून्य पॉइंटर्स क्या हैं?

उनका उपयोग क्या है? क्या मैं उन्हें किसी भी प्रकार के चर के लिए इंगित कर सकता हूं?

उत्तर

20
मूल रूप से

, सी

उनके उपयोग क्या है से एक अवशेष?

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

क्या मैं उन्हें किसी भी प्रकार के चर के लिए इंगित कर सकता हूं?

हां। हालांकि, जैसा कि अन्य ने इंगित किया है, आप सीधे शून्य सूचक का उपयोग नहीं कर सकते हैं - आपको इसे पहले एक ठोस डेटा प्रकार में पॉइंटर में डालना होगा।

+0

इससे चीजें ... दिलचस्प बनाती हैं। आपके त्वरित उत्तर के लिए धन्यवाद :) मुझे पता है कि यह शायद खराब अभ्यास है लेकिन कुछ मामलों में यह मेरे लिए बहुत उपयोगी हो सकता है! –

+9

यदि आप सी ++ (और सी नहीं) में लिख रहे हैं, तो 'शून्य *' का उपयोग करना लगभग हमेशा गलत काम है। इन मामलों को संभालने के लिए * सही * तरीकों की तलाश करके अपने सी ++ कौशल में सुधार क्यों न करें? –

+0

जबकि मैं इस बात से असहमत नहीं हूं कि शून्य * से बचा जाना चाहिए, क्योंकि आमतौर पर सी ++ में चीजों को करने के बेहतर तरीके हैं, फिर भी कुछ असामान्य मामले हैं जहां वे मूल्यवान या आवश्यक हैं। उत्तरार्द्ध का एक उदाहरण यह निर्धारित कर रहा है कि संदर्भों की एक जोड़ी एक ही वस्तु के लिए है, जब संदर्भ बहुगुणित विरासत वाले ऑब्जेक्ट के विभिन्न अभिभावक वर्गों के लिए हैं। –

7

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

4
cplusplus.com से

:

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

यह शून्य पॉइंटर्स को किसी भी डेटा प्रकार को इंगित करने की अनुमति देता है, एक पूर्णांक मान या अक्षरों की एक स्ट्रिंग पर एक फ्लोट। लेकिन बदले में वे एक महान सीमा: डेटा उनके द्वारा बताया सीधे dereferenced नहीं किया जा सकता है (जो तार्किक है, क्योंकि हम भिन्नता के लिए करने के लिए कोई प्रकार है), और यही कारण है के लिए हम हमेशा कास्ट करने के लिए होगा शून्य सूचक में कुछ अन्य पॉइंटर प्रकार जो से पहले कंक्रीट डेटा प्रकार को इंगित करता है, को संदर्भित करता है।

6

सी ++ में शून्य पॉइंटर्स के लिए मौजूद कुछ उपयोगों में से एक है new ऑपरेटरों को ओवरलोड करने में उनका उपयोग। परिभाषा के अनुसार सभी new ऑपरेटर void* टाइप करते हैं। इसके अलावा, दूसरों ने जो कहा है वह सच है।

1

एक शून्य सूचक अपनी स्मृति :-)

सी मानक कहा गया है कि आप एक शून्य-सूचक के लिए किसी भी सूचक परिवर्तित कर सकते हैं, तो कुछ भी खोने के बिना इसे वापस डाली के रूप में, कुछ भी करने के लिए इंगित कर सकते हैं जब तक।

0

शून्य पीआरटी मूल रूप से एक खाली बॉक्स है। जो भी आप चाहते हैं उसे भरें लेकिन सुनिश्चित करें कि आप इसे लेबल करते हैं (tupecasting)

+2

मुझे लगता है कि आपका मतलब "टाइपकास्टिंग" है, हालांकि "tuplecasting" एक रोमांचक नए प्रतिमान के नाम की तरह लगता है बस खोज की प्रतीक्षा कर रहा है। – AShelly

+0

मुझे लगता है कि 'tupecasting'' अपकास्टिंग 'के लिए एक टाइपो है। ऐसा कहकर, आप एक विशिष्ट प्रकार के लिए शून्य तक पहुंच गए। –

0

मैं उन्हें अपनी गतिशील सूचियों में अधिक प्रकार की वस्तुओं (सभी पॉइंटर्स) रखने के लिए उपयोग करता हूं।
typedef void* Object; फिर जब आप ऑब्जेक्ट वैरिएबल घोषित करते हैं तो आप इसमें कोई पॉइंटर स्टोर कर सकते हैं। जरूरतों के आधार पर यह कम या ज्यादा उपयोगी है।
मुझे यह बहुत उपयोगी लगता है जब आपको कहीं भी कोई पॉइंटर स्टोर करना होता है और आप केवल अपनी सभी कक्षाओं को सिर्फ एक ही नहीं प्राप्त कर सकते हैं। इसके अलावा अन्य लोगों ने कहा कि टेम्पलेट्स, पॉलिमॉर्फिज्म इत्यादि का उपयोग करना बेहतर है

+3

बूस्ट की तरह कुछ :: किसी भी या boost :: संस्करण को शून्य * के अधिकांश उपयोगों के लिए बेहतर तरीके से कार्य किया जा सकता है। –

1

void पर एक सूचक एक असेंबली भाषा सूचक के लिए निकटतम अवधारणा है। यह एक सामान्य सूचक है जो किसी पते या स्थान (फ़ंक्शन या डाटाम) के स्थान के लिए स्थान सुरक्षित रखता है। जैसा कि अन्य ने कहा है, इसे अस्वीकार करने से पहले इसे कास्ट किया जाना चाहिए।

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

4

छिपाएं टाइप करें। आधुनिक सी ++ में इसका अभी भी वैध उपयोग है। बूस्ट में स्रोत कोड के माध्यम से खोदें और आपको कुछ मिलेंगे। आम तौर पर एक शून्य * का उपयोग एक जटिल परिसर के आंतों के भीतर बहुत गहरा दफनाया जाता है जो काले और बुरे जादू के दौरान इंटरफ़ेस की प्रकार की सुरक्षा सुनिश्चित करता है।

3

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

जो मुझे समझ में नहीं आता है, लोगों ने क्यों न केवल अपरिभाषित प्रकारों का उपयोग किया है, यानी अपारदर्शी पॉइंटर्स। सुरक्षा, उपयोगकर्ता डेटा टाइप करें।

आधुनिक सी ++ में, पॉइंटर-टू-शून्य पूरी तरह से पॉलिमॉर्फिज्म और टेम्पलेट से उत्पन्न जेनेरिक कोड द्वारा अधिग्रहण किया जाता है। हालांकि, आपको मूल सी कोड के साथ इंटरफेस करने के लिए अभी भी उनका उपयोग करना पड़ सकता है। किसी भी संदर्भ में, शून्य से * सुरक्षित रूप से उपयोग करने के लिए, केवल एक प्रकार को एक शून्य * पर डाला गया है। इस तरह, आप निश्चित रूप से जानते हैं कि यह क्या इंगित करता है। आप अधिक प्रकार की जरूरत है, आप एक त्वरित
struct safevoidptr { base* ptr };
या
struct safevoidptr { void* ptr; int type; };
मुझे विश्वास है कि dynamic_cast भी बहुरूपी प्रकार के लिए शून्य * कन्वर्ट करने के लिए सक्षम हो सकता है, हालांकि मैं dynamic_cast इस्तेमाल कभी नहीं किया है, इसलिए नहीं लेते मेरी बात कर सकता है इसके लिए।

0

चीजें आप नहीं कर सकते C++ शून्य के साथ सी में कर सकता है, लेकिन:

शून्य * के स्वचालित रूप से अन्य सूचक प्रकार के लिए बदल रहे हैं। (तुम्हें पता है इसकी एक शून्य * - आप एक स्पष्ट कलाकारों के लिए मजबूर कर से कोई प्रकार सुरक्षा हासिल)

Struct* p = malloc(sizeof(Struct)); 
// vs C++ 
Struct* p = (Struct*)malloc(sizeof(Struct)); 
// Some will argue that that cast style is deprecated too, and c++ programmers 
// need to actually do this: 
Struct* p = reinterpret_cast<Struct*>malloc(sizeof(Struct)); 
// See what C++ did there? By making you write Struct a 3rd time, you can now be sure 
// you know what you are doing! 

शून्य * की भी सी में अविवेक गिनती किया था, अधिक से अधिक सुरक्षा के लिए अनुमति देता है जब कार्यों है कि एक लेने के लिए संकेत गुजर एक सूचक के लिए सूचक।टेम्पलेट विशेषज्ञता:

void funcInitializingOutPtr(void** ppOut) 
{ 
    *ppOut = malloc(x); 
} 

int* out = NULL; 
funcInitializingPtr(out); // C would signal this as an error 
funcInitializingPtr(&out); // correct 
// vs C++ 
funcInitializingPtr((void**)&out); // so much safer needing that exlicit cast. 
funcInitializingPtr((void**)out); // oops. thanks C++ for hiding the common error 
1

चूंकि पहले से ही इतने सारे अच्छे उत्तर दिए गए हैं, मैं सिर्फ और अधिक सामान्य से एक मैंने देखा में से एक उपलब्ध कराएंगे। अगर मुझे गलत तरीके से याद नहीं है, तो स्ट्रॉस्ट्रप बुक का इसका एक उदाहरण है: वेक्टर के रूप में वेक्टर को विशेषज्ञता देना, फिर वेक्टर से वेक्टर (निजी तौर पर) प्राप्त करना। इस तरह, वेक्टर में केवल सरल आसानी से रेखांकित कोड होंगे (यानी वेक्टर से प्रासंगिक कार्यों को कॉल करें)। यह एक प्रोग्राम में वेक्टर संकलित होने पर डुप्लिकेशन की संख्या को कम करेगा जो कई अलग-अलग प्रकार के पॉइंटर्स के साथ इसका उपयोग करता है।

0

मैं बेलीव शून्य * स्मृति स्थान है जहां आप कुछ भी टाइप/स्टोर कर सकते हैं। मैं कुछ भाषा पंडित इस पर असहमत हूं। लेकिन मैंने इसे अपने कई प्रोजेक्ट में सफलतापूर्वक उपयोग किया है।

केवल समस्या जो मैं देखता हूं वह टाइपफ़ाइट

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