2010-06-15 11 views
10

इस बिंदु पर सी ++ का मेरा ज्ञान किसी और चीज से अधिक शैक्षणिक है। अब तक मेरे सभी पढ़ने में, नामित कास्ट (const_cast, static_cast, reinterpret_cast, dynamic_cast) के साथ स्पष्ट रूपांतरण का उपयोग एक बड़ा चेतावनी लेबल (और यह देखना आसान है) के साथ आया है जिसका अर्थ है कि स्पष्ट रूपांतरण खराब डिजाइन का लक्षण है और केवल बेताब परिस्थितियों में अंतिम उपाय के रूप में उपयोग किया जाना चाहिए। तो, मैं पूछने के लिए:क्या सी ++ स्पष्ट रूपांतरण वास्तव में बुरा है?

नामित साथ स्पष्ट रूपांतरण वास्तव में सिर्फ जूरी हेराफेरी कोड डाले या वहाँ इस सुविधा के लिए एक और अधिक सुंदर और सकारात्मक आवेदन है है? क्या उत्तरार्द्ध का एक अच्छा उदाहरण है?

उत्तर

19

रहे मामलों रहे हैं जब आप बस इसे बिना नहीं जा सकते। this one की तरह। समस्या आप एकाधिक वंशानुक्रम है और void* को this सूचक कन्वर्ट करने के लिए है, जबकि यह सुनिश्चित करना कि सूचक है कि void* में चला जाता है अभी भी चालू वस्तु की सही subobject को इंगित करेगा कि जरूरत होती है। एक स्पष्ट कलाकार का उपयोग करना इसे प्राप्त करने का एकमात्र तरीका है।

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

+9

मैं यहां तीर्थतुथ की अंतिम टिप्पणी से सहमत हूं, सिर्फ इसलिए कि आपके पास एक स्पष्ट कलाकार है, इसका मतलब यह नहीं है कि आपके पास खराब कोड है, लेकिन यदि आप वापस दूसरी पंक्ति को कास्टिंग और अग्रेषित कर रहे हैं तो आपको चीजों पर पुनर्विचार करना होगा। कास्टिंग एक वैध ऑपरेशन है लेकिन यह ऐसा कुछ है जिसे इस्तेमाल नहीं किया जाना चाहिए। –

+1

निश्चित रूप से संकलन चेतावनियों और त्रुटियों को दूर करने के लिए कभी भी उपयोग नहीं किया जाता है! – Alan

11

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

सामान्य में, स्पष्ट डाले का उपयोग एक रेड हेरिंग है। इसका मतलब खराब कोड नहीं है, लेकिन यह संभावित खतरनाक उपयोग पर ध्यान आकर्षित करता है।

हालांकि आप एक ही बैग में 4 डाले फेंक नहीं करना चाहिए: static_cast और dynamic_cast अक्सर कास्टिंग (बेस से व्युत्पन्न करने के लिए) या संबंधित प्रकार के बीच नेविगेट करने के लिए उपयोग किया जाता है। कोड में उनकी घटना काफी सामान्य है (वास्तव में बिना किसी के Visitor पैटर्न लिखना मुश्किल है)।

दूसरी ओर, const_cast और reinterpret_cast का उपयोग अधिक खतरनाक है।

  • const_cast उपयोग का प्रयास करें और केवल पढ़ने के लिए वस्तु को संशोधित करने के अपरिभाषित व्यवहार (सुधार के लिए जेम्स McNellis करने के लिए धन्यवाद)
  • reinterpret_cast सामान्य रूप से केवल कच्चे स्मृति से निपटने के लिए प्रयोग किया जाता है (allocators)

है उनके पास उनका उपयोग निश्चित रूप से है, लेकिन सामान्य कोड में इसका सामना नहीं किया जाना चाहिए। बाहरी या सी एपीआई से निपटने के लिए हालांकि आवश्यक हो सकता है।

कम से कम यह मेरी राय है।

+1

तकनीकी रूप से यह 'const_cast' के परिणामस्वरूप केवल पढ़ने योग्य वस्तु है _ जिसके परिणामस्वरूप अपरिभाषित व्यवहार होता है। 'Const_cast' स्वयं" सुरक्षित "है। –

+0

धन्यवाद, मैंने तदनुसार वाक्य को tweaked। प्रभावी रूप से किसी भी कास्ट अपने आप में सुरक्षित है, यह केवल उस परिणाम का उपयोग कर रहा है जो अपरिभाषित व्यवहार का आह्वान कर सकता है। –

+0

COM एक सी ++ लाइब्रेरी नहीं है और इसलिए इसे अच्छे सी ++ अर्थशास्त्र के साथ दिमाग में डिजाइन नहीं किया गया था। यह बुरा नहीं बनाता है - यह केवल अपने स्वयं के ऑब्जेक्ट मॉडल को परिभाषित करता है। (COM * अन्य * कारणों के लिए एक पिटा है) –

3

आईएमओ, ज्यादातर चीजों की तरह, वे उचित उपयोग और अनुचित लोगों के साथ उपकरण हैं। कास्टिंग शायद एक ऐसा क्षेत्र है जहां औजारों को अक्सर अनुपयुक्त रूप से उपयोग किया जाता है, उदाहरण के लिए, int और reinterpret_cast (जो प्लेटफ़ॉर्म पर दो अलग-अलग आकार होते हैं) के साथ पॉइंटर प्रकार के बीच डालने के लिए, या const_cast को पूरी तरह से एक हैक के रूप में स्थिरता , और इसी तरह।

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

6

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

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

reinterpret_cast हमेशा मंच-निर्भर होने जा रहा है, और इसलिए पोर्टेबल कोड में सबसे अच्छा संदिग्ध है। इसके अलावा, जब तक आप वस्तुओं की भौतिक संरचना पर निम्न स्तर के संचालन नहीं कर रहे हैं, यह अर्थ को संरक्षित नहीं करता है। सी और सी ++ में, एक प्रकार का अर्थपूर्ण होना चाहिए। एक int एक संख्या है जिसका अर्थ कुछ है; एक int जो मूल रूप से char एस का संयोजन है, वास्तव में कुछ भी मतलब नहीं है।

dynamic_cast आमतौर पर डाउनकास्टिंग के लिए उपयोग किया जाता है; जैसे Base * से Derived * तक, यह साबित करने के साथ कि यह या तो यह काम करता है या यह 0 देता है। यह एक प्रकार के टैग पर switch कथन के रूप में ओओ को बहुत अधिक करता है: यह कोड को परिभाषित करता है जो परिभाषित करता है कि कक्षा परिभाषा से कक्षा क्या है । यह अन्य कोड के साथ कक्षा परिभाषाओं को जोड़ता है और संभावित रखरखाव भार बढ़ाता है।

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

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

1

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

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


बाहर की जाँच करें और अधिक सुक्ष्म बढ़ावा रूपांतरण पुस्तकालय में इस तरह के रूप में इन polymorphic_cast डाले में बदलाव,,, तुम बस कैसे सावधान सी ++ प्रोग्रामर हैं, जब यह कास्टिंग की बात आती है की एक विचार देने के लिए।

1

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

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