2010-02-27 10 views
12

मैं सी ++ कास्टिंग के बारे में बहुत कुछ पढ़ रहा हूं और मुझे उलझन में लग रहा है क्योंकि मैंने हमेशा सी शैली कास्टिंग का उपयोग किया है।सी ++ कास्टिंग पर उलझन

मैंने पढ़ा है कि सी शैली कास्टिंग सी ++ में टालना चाहिए और यह कि reinterpret_cast बहुत खतरनाक है और जब भी कोई विकल्प होता है तब इसका उपयोग नहीं किया जाना चाहिए। Reinterpret_cast का उपयोग न करने के विपरीत, मैंने इसे अपने नमूना कोड में एमएसडीएन पर कई बार इस्तेमाल किया है। इससे मुझे मेरा पहला सवाल पूछने की ओर अग्रसर किया जाता है, reinterpret_cast का उपयोग करना कब ठीक है?

उदाहरण के लिए:

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (Msg) 
    { 
     case WM_CREATE: 
     { 
      LPCREATESTRUCT lpCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam); 
      return 0; 
     } 
    } 

    ... 
} 

अगर ऐसा है नहीं ठीक है, तो मैं कैसे केवल, स्थिर गतिशील, और/या स्थिरांक कास्टिंग का उपयोग कर एक सूचक को lParam मूल्य डाली हैं?

इसके अलावा: यदि reinterpret_cast पोर्टेबल नहीं है, मैं इसे कैसे (अच्छा अभ्यास के लिए)

+1

यह बहुत पुराना कोड बेस हो सकता है। –

उत्तर

8

पोर्टेबल reinterpret_cast का उपयोग करना स्वीकार्य है अगर आपको लगता है कि सूचक गंतव्य प्रकार के मूल रूप से था होना करने के लिए फिर से लिखने होगा। कोई भी अन्य उपयोग कार्यान्वयन-निर्भर व्यवहार का लाभ उठा रहा है, हालांकि कई मामलों में यह आवश्यक और उपयोगी है, जैसे किसी सूचक को बाइट्स में एक सूचक में एक सूचक को कास्टिंग करना ताकि इसे क्रमबद्ध किया जा सके।

इसे खतरनाक माना जाता है क्योंकि यह संकलन-समय या रनटाइम पर या तो जांच नहीं करता है। यदि आप कोई गलती करते हैं, तो यह क्रैश हो सकता है और क्रोधित हो जाएगा और डीबग करना मुश्किल होगा। आप अनिवार्य रूप से संकलक को बता रहे हैं "मैं वास्तव में आपके से बेहतर जानता हूं, इसलिए बस कोड संकलित करें और मुझे परिणामों के बारे में चिंता करने दें।"

+1

इस तरह से स्ट्रक्चर को व्यवस्थित करना एक बुरा विचार है (भले ही अक्सर किया जाता है), लेकिन यह एक और प्रश्न के लिए एक विषय है। – Tronic

5

क्योंकि Win32 एपीआई एक सी एपीआई है, लेकिन लोगों को सी ++ में उदाहरण देकर पर जोर देते हैं कारण आप MSDN पर इसे देख रहा है।

जब आप अन्य पुस्तकालयों के साथ इंटरफेस करते हैं तो कोड लिख रहे हैं तो पुन: परिभाषित करें ठीक है। इसे अपने स्वयं के ऐप के भीतर से बचा जाना चाहिए।

2

एमएसडीएन का अनादर नहीं करना है, लेकिन एमएसडीएन उचित सी ++ कोडिंग के लिए जाने का सबसे अच्छा स्थान नहीं है।

reinterpret_cast का उपयोग करने का एक कारण यह है कि जब आप अपारदर्शी डेटाटाइप से/कास्टिंग कर रहे हैं। reinterpret_cast "खतरनाक" नहीं है, यह सिर्फ इतना है कि स्क्रू करना आसान है और आपके कोड में समस्याएं पैदा होती हैं, यही कारण है कि इसे टालना चाहिए।

सी ++ स्टाइल कास्ट पसंद करने का कारण यह है कि, static_cast टाइपएफ़ है, और सभी कास्टिंग समय खोजना आसान है।

प्रोग्रामर [गलत तरीके से] अक्सर "कंपाइलर चेतावनियों को कास्ट" करने के लिए कास्ट का उपयोग करते हैं जैसे कि हस्ताक्षरित हस्ताक्षरित पूर्णांक में परिवर्तित करना, या 32 बिट पूर्णांक से 8 बिट तक।

+1

+1। एमएसडीएन एमएस-आईएमएस से भरा हुआ है। स्कॉट मेयर्स और हर्ब सटर द्वारा अच्छी किताबें (हालांकि वह अब एमएस में हैं, वह एक उत्कृष्ट लेखक हैं और अच्छे सी ++ लिखने पर बहुत अच्छी सलाह है) अच्छी सी ++ अभ्यास की समझ को समझने के लिए बेहतर जगह हैं। –

+0

@ मैट कर्टिस - मुझे एमएसडीएन के बारे में अधिक परेशान करने वाला हिस्सा मिल गया है कि एमएस-इस्लाम असंगत रूप से लागू होते हैं। गुणवत्ता उनके उदाहरणों के साथ बहुत भिन्न होती है। आम तौर पर, हालांकि, आपको उनके उदाहरणों की प्रतिलिपि बनाना नहीं चाहिए; यह आपको एक मोटा विचार दे सकता है लेकिन आपको उन विचारों को अनुकूलित करना चाहिए जो आप जिस परियोजना पर काम कर रहे हैं उसमें कोडिंग शैली का उपयोग किया जाता है। – asveikau

2

मूलतः reinterpret_cast सी संरचनाओं और बुनियादी प्रकार (एक सूचक और वापस, जो ILP32 वास्तुकला लेकिन LP64 एक पर टूट जाता है पर काम करता है के लिए int कास्टिंग की तरह सादा गलतियों baring।) एसी संरचना उस में कुछ भी नहीं है के साथ "सुरक्षित" है , संरेखण के लिए संभावित पैडिंग को छोड़कर, आपने घोषणा नहीं की थी।आभासी टेबल और आभासी आधार वर्ग की ओर इशारा करने के लिए संकेत है - जैसे के बाद से संकलक अपनी कक्षा में डेटा आइटम सम्मिलित करता

reinterpret_cast सी ++ बहुरूपी प्रकार के साथ सुरक्षित नहीं है। अन्य सी ++ कास्ट इन्हें समायोजित करने का ख्याल रखता है, कहता है, पॉइंटर से बेस क्लास तक पॉइंटर से व्युत्पन्न कक्षा में डाउन-कास्टिंग, reinterpret_cast और सी-स्टाइल कास्ट नहीं होता है।

3

यह सी ++ के साथ एक विंडोज एपीआई, विंडोज प्लेटफार्म एसडीके प्रोग्रामिंग का एक उदाहरण है। खिड़की की प्रक्रिया में केवल WPARAM और LPARAM पैरामीटर हैं और यदि आपको विंडो संदेश के माध्यम से किसी संरचना में पॉइंटर पास करने की आवश्यकता है, तो इसे कास्ट करना होगा। यह मेरी राय में reinterpret_cast <> का एक पूरी तरह से स्वीकार्य उपयोग है। आप एक कलाकार से बच नहीं सकते हैं क्योंकि आप जिस एसडीके को लिख रहे हैं, जो आपका कोड नहीं है, सी ++ के लिए डिज़ाइन नहीं किया गया था, बहुत कम प्रकार की सुरक्षा, और सी बाध्यकारी के साथ जेनेरिक पैरामीटर प्रकार प्रदान करने के लिए कास्टिंग की आवश्यकता है।

reinterpret_cast <> यहां एक ध्वज है जो आपको बताता है कि आपको सावधान रहने की आवश्यकता है, लेकिन इसे हर कीमत से टालना नहीं है।

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

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