Static_cast और reinterpret_cast दोनों ही एक अन्य पॉइंटर टाइप * शून्य की कास्टिंग के लिए ठीक काम करते हैं। क्या एक दूसरे पर एहसान करने का एक अच्छा कारण है?
Static_cast और reinterpret_cast दोनों ही एक अन्य पॉइंटर टाइप * शून्य की कास्टिंग के लिए ठीक काम करते हैं। क्या एक दूसरे पर एहसान करने का एक अच्छा कारण है?
जवाबों:
उपयोग करेंstatic_cast
: यह सबसे संकीर्ण कास्ट है जो वास्तव में वर्णन करता है कि यहां क्या रूपांतरण किया गया है।
एक गलत धारणा है कि इसका उपयोग reinterpret_cast
एक बेहतर मैच होगा क्योंकि इसका मतलब है "पूरी तरह से सुरक्षा को अनदेखा करना और ए से बी तक कास्ट करना"।
हालांकि, यह वास्तव में एक के प्रभाव का वर्णन नहीं करता है reinterpret_cast
। बल्कि, इसके reinterpret_cast
कई अर्थ हैं, जिनमें से सभी के लिए यह है कि "द्वारा निष्पादित मानचित्रण reinterpret_cast
कार्यान्वयन-परिभाषित है।" [5.2.10.3]
लेकिन से कास्टिंग के विशेष मामले में void*
करने के लिए T*
मानचित्रण पूरी तरह से मानक से अच्छी तरह से परिभाषित है, अर्थात्, अपने पते को बदले बिना एक टाइप्ड पॉइंटर को टाइप करने के लिए।
यह पसंद करने का एक कारण है static_cast
।
इसके अतिरिक्त, और यकीनन अधिक महत्वपूर्ण है, यह तथ्य यह है कि इसका हर उपयोग reinterpret_cast
सर्वथा खतरनाक है क्योंकि यह किसी भी चीज़ को वास्तव में (बिंदुओं के लिए) में परिवर्तित करता है, जबकि static_cast
यह अधिक प्रतिबंधात्मक है, इस प्रकार यह एक बेहतर स्तर की सुरक्षा प्रदान करता है। इससे मुझे पहले ही बग से बचाया जा चुका है जहां मैंने गलती से एक पॉइंटर टाइप को दूसरे में डालने की कोशिश की थी।
यह एक मुश्किल सवाल है। एक ओर, कोनराड पुन: व्याख्या_कास्ट के लिए विशिष्ट परिभाषा के बारे में एक उत्कृष्ट बिंदु बनाता है , हालांकि व्यवहार में यह संभवतः एक ही बात करता है। दूसरी ओर, यदि आप पॉइंटर प्रकारों के बीच कास्टिंग कर रहे हैं (जैसा कि एक चार के माध्यम से मेमोरी में अनुक्रमित करते समय काफी सामान्य है), उदाहरण के लिए, static_cast एक संकलक त्रुटि उत्पन्न करेगा और आपको वैसे भी reinterpret_cast का उपयोग करने के लिए मजबूर किया जाएगा ।
व्यवहार में मैं पुनर्व्याख्या_का उपयोग करता हूं क्योंकि यह कास्ट ऑपरेशन के इरादे के बारे में अधिक वर्णनात्मक है। आप निश्चित रूप से एक अलग ऑपरेटर के लिए पॉइंटर रीइंटरपॉइंट करने के लिए केवल एक केस बना सकते हैं (जो उसी पते की गारंटी देता है), लेकिन मानक में कोई नहीं है।
reinterpret_cast
!
मैं हमेशा सबसे कमजोर संभव कलाकारों का उपयोग करने का सुझाव देता हूं।
reinterpret_cast
एक करने के लिए एक सूचक डालने के लिए इस्तेमाल किया जा सकता है float
। कलाकारों को जितना अधिक संरचना-तोड़ना होता है, उसका उपयोग करने के लिए उतना ही अधिक ध्यान देने की आवश्यकता होती है।
के मामले में char*
, मैं सी-स्टाइल कास्ट का उपयोग करूंगा, जब तक कि हमारे पास कुछ न हो reinterpret_pointer_cast
, क्योंकि यह कमजोर है और कुछ भी पर्याप्त नहीं है।
float f = *reinterpret_cast<const float*>(&p);
float
, जो कि गलत है। अभिव्यक्ति को बदलने के लिए जाती void **
है const float *
, और फिर एक dereference ऑपरेशन (जो एक कास्ट नहीं है) का उपयोग करता है, को बदलने के const float *
लिए float
।
मेरी व्यक्तिगत प्राथमिकता इस तरह कोड साक्षरता पर आधारित है:
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
या
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
वे दोनों अंत में एक ही करते हैं, लेकिन static_cast मध्य-वेयर, ऐप एनवायरमेंट में अधिक उपयुक्त लगता है, जबकि पुनर्व्याख्या कास्ट ऐसा लगता है जैसे आप निम्न-स्तरीय लाइब्रेरी IMHO में देखेंगे।