2017-06-30 11 views
23

मैं समझता हूं कि static_cast एक प्रकार से दूसरे में एक कास्ट है (सहजता से) एक ऐसी कलाकार है जो कुछ परिस्थितियों में सफल हो सकती है और खतरनाक कलाकारों की अनुपस्थिति में सार्थक हो सकती है। इस बीच, reinterpret_cast एक कलाकार है जो एक असुरक्षित रूपांतरण का प्रतिनिधित्व करता है जो एक मूल्य के बिट्स को किसी अन्य मूल्य के बिट्स के रूप में दोबारा परिभाषित कर सकता है।सी ++ प्रकार कास्टिंग। Static_cast सफल कब होगा और reinterpret_cast एक समस्या का कारण बन जाएगा?

क्या किसी व्यक्ति परिदृश्य का वर्णन कर सकता है जब कोड संकलित, कास्ट और static_cast कोई समस्या नहीं होगी, लेकिन reinterpret_cast के साथ कोई समस्या होगी?

+0

कोई भी 'reinterpret_cast' जिसे मानक में अच्छी तरह से परिभाषित नतीजे के रूप में सूचीबद्ध नहीं किया गया है, समस्याएं पैदा कर सकता है, और कम से कम प्रोग्राम को औपचारिक रूप से खराब बना देता है। –

+4

एकाधिक विरासत के साथ बेस क्लास में कास्टिंग –

उत्तर

20

यह यह करना होगा:

#include <iostream> 
using namespace std; 

struct C{int n;}; 
struct A{int n;}; 
struct B : A, C{}; 

int main() 
{ 
    B b; 
    B* pb = &b; 
    cout << static_cast<C*>(pb) << "\n"; 
    cout << reinterpret_cast<C*>(pb); 
} 

नोट दो पते में मतभेद।

मैंने यहां कुछ बहु विरासत बनाए हैं, और आधार वर्गों में खाली आधार वर्गों के संभावित अनुकूलन को रोकने के लिए बेस क्लास में एक स्पष्ट सदस्य रखा है।

देखें https://ideone.com/QLvBku

+4

नोट: बिना बहु-विरासत के, वर्चुअल विधियों के बिना बेस क्लास और वर्चुअल विधि वाले व्युत्पन्न क्लास "v-ptr" आकार (प्लस संभावित पैडिंग) का ऑफसेट उत्पन्न करेगा। –

9

ऐसे मामलों में से एक एकाधिक विरासत है - static_cast पते का समायोजन करता है (इसलिए कच्चे ऑब्जेक्ट पॉइंटर का पता व्युत्पन्न ऑब्जेक्ट पते से अलग हो सकता है, सही बेस क्लास आइटम्स को इंगित करने के लिए)।

reinterpret_cast कोई पता समायोजन नहीं करता है, इसलिए बेस क्लास में कास्ट गलत पता का उपयोग कर सकता है (यानी हमेशा व्युत्पन्न वस्तु का पता अपरिवर्तित होता है)।

15

सरलतम इस तरह के मामले reinterpret_cast<void*>(NULL) है, जो एक गैर-शून्य सूचक उपज सकता है।

इसके विपरीत, static_cast<void*>(NULL) सुरक्षित है क्योंकि इसे एक शून्य सूचक उत्पन्न करने की आवश्यकता है।

क्यों? NULL एक पूर्णांक स्थिर 0 के बराबर है। static_cast की आवश्यकता है कि 0 को उचित शून्य सूचक में परिवर्तित किया जाए, लेकिन reinterpret_cast में यह वही आवश्यकता नहीं है। यदि एक शून्य सूचक का आंतरिक प्रतिनिधित्व पूर्णांक शून्य के समान नहीं है, तो परिणाम अलग होंगे। खंडित पते के साथ आर्किटेक्चर पर इस प्रकार का ब्रेकेज सबसे अधिक संभावना होगी।

+0

मुझे यह आश्चर्यजनक लगता है। क्या आप आगे विस्तार कर सकते हैं कि कैसे/क्यों 'reinterpret_cast (NULL)' गैर-शून्य वापस आ सकता है? – Cornstalks

+2

'reinterpret_cast' के लिए सीपीपी संदर्भ कहता है "* शून्य सूचकांक निरंतर' न्यूल 'या पूर्णांक शून्य को लक्ष्य प्रकार के शून्य सूचक मूल्य को प्राप्त करने की गारंटी नहीं है;' static_cast' या अंतर्निहित रूपांतरण इस उद्देश्य के लिए उपयोग किया जाना चाहिए। * " –

+0

@TobySpeight: और 'nullptr' का क्या? मुझे उम्मीद है कि यह तय किया गया था ... –

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