यह प्रश्न here टिप्पणियों से प्रेरित है।क्या मानक-अनुपालन संकलक गैर-पॉलिमॉर्फिक प्रकार से डायनामिक_कास्ट डाउनकास्ट युक्त कोड को अस्वीकार कर सकता है?
पर विचार करें निम्नलिखित कोड का टुकड़ा:
struct X {}; // no virtual members
struct Y : X {}; // may or may not have virtual members, doesn't matter
Y* func(X* x) { return dynamic_cast<Y*>(x); }
कई लोगों ने सुझाव दिया है कि उनके संकलक func
के शरीर अस्वीकार होगा।
हालांकि, मुझे लगता है कि मानक द्वारा परिभाषित किया गया है कि x
के रन-टाइम मान पर निर्भर करता है। खंड 5.2.7 ([expr.dynamic.cast]
) से:
अभिव्यक्ति
dynamic_cast<T>(v)
का परिणाम अभिव्यक्तिv
परिवर्तित टाइप करने के लिएT
का परिणाम है।T
एक पूर्ण श्रेणी प्रकार के संदर्भ में एक सूचक या होगा, या "सीवीvoid
पर सूचक।"dynamic_cast
ऑपरेटर स्थिरता को दूर नहीं करेगा।तो
T
एक सूचक प्रकार है,v
पूरा करने के लिए वर्ग प्रकार एक सूचक की एक prvalue होगा, और परिणाम प्रकारT
के prvalue है। यदिT
एक लाभा संदर्भ प्रकार है,v
एक पूर्ण श्रेणी प्रकार का एक आभासी होगा, और परिणामT
द्वारा निर्दिष्ट प्रकार का एक अंतराल है। यदिT
एक रैवल्यू संदर्भ प्रकार है,v
एक पूर्ण वर्ग प्रकार, वाला एक अभिव्यक्ति होगा और परिणामT
द्वारा निर्दिष्ट प्रकार का एक xvalue होगा।तो
v
की प्रकारT
रूप में ही है, या यह एक ही है के रूप मेंT
सिवाय इसके किT
में वर्ग ऑब्जेक्ट प्रकारv
में वर्ग ऑब्जेक्ट प्रकार की तुलना में अधिक सीवी-योग्य है, परिणाम हैv
(यदि आवश्यक हो तो परिवर्तित)।तो
v
का मूल्य सूचक मामले में एक नल पॉइंटर मूल्य है, परिणाम प्रकारT
के नल पॉइंटर मूल्य है।तो टी है "सूचक को CV1
B
" औरv
'सूचक CV2D
करने के लिए "ऐसी है किB
D
का एक आधार वर्ग है टाइप किया है, परिणाम अद्वितीयB
करने के लिए एक सूचक हैD
ऑब्जेक्ट का उपरोक्तv
द्वारा इंगित किया गया। इसी तरह, अगर टी औरv
"CV1B
के संदर्भ में" है परिणामD
वस्तुv
से संबोधित किया जाता का अनूठाB
subobject है टाइप CV2D
ऐसी है किB
D
का एक आधार वर्ग है,। नतीजा यह है किT
एक लाभा संदर्भ है, याT
एक रावल्यू संदर्भ है, तो एक अंडाकार है। दोनों सूचक और संदर्भ मामलों में, कार्यक्रम बीमार बनाई है अगर CV2CV1 से अधिक से अधिक सीवी-योग्यता है याB
एक दुर्गम याD
की अस्पष्ट आधार वर्ग है यदि।अन्यथा,
v
एक पॉइंटरॉर्फिक प्रकार के पॉइंटर या एक लाइव्यू होगा।तो
T
है "सूचक सीवीvoid
लिए," तो परिणाम सबसे व्युत्पन्न वस्तु के लिए एक सूचकv
द्वारा की ओर इशारा किया है। अन्यथा, एक रन-टाइम जांच को देखने के लिए अन्य शामिल कर सकते हैं प्रकार उठाई याT
द्वारा कहा जाता है।) में बदला जा सकता लागू किया जाता है, तो वस्तु बताया या करने के लिए भेजाv
द्वारा सबसे व्युत्पन्न वस्तु बताया या करने के लिए भेजाv
द्वाराB
बेस क्लास के रूप में ऑब्जेक्ट्स, लेकिन इन्हें अनदेखा किया जाता है।हैं
C
वर्ग प्रकार है जो करने के लिएT
अंक या संदर्भित करता है, रन-टाइम जांच तार्किक कार्यान्वित इस प्रकार है:
हैं, तो सबसे व्युत्पन्न वस्तु बताया (कहा जाता है) में से करने के लिए
v
,v
अंक (संदर्भित करता है) एकC
वस्तु का एकpublic
आधार वर्ग subobject के लिए, और प्रकारC
का केवल एक ही वस्तु ०१२३९९२७८९७३ द्वारा करने के लिए subobject बताया (कहा जाता है) से ली गई है, तो परिणाम अंक (संदर्भ) उसC
ऑब्जेक्ट पर।अन्यथा, यदि
v
अंक (संदर्भित करता है) सबसे व्युत्पन्न वस्तु, और सबसे व्युत्पन्न वस्तु के प्रकार की एकpublic
आधार वर्ग subobject करने के लिए एक आधार वर्ग, प्रकारC
की, कि स्पष्ट है औरpublic
है , परिणाम बिंदु (संदर्भ)C
सबसे व्युत्पन्न वस्तु का सबोबजेक्ट।अन्यथा, रन-टाइम चेक विफल रहता है।
सूचक प्रकार के एक असफल कलाकारों के मूल्य अपेक्षित परिणाम प्रकार की अशक्त सूचक मान है। संदर्भ
std::bad_cast
को संदर्भित करने में असफल कलाकार।
तरह से मैं यह पढ़, एक बहुरूपी प्रकार की आवश्यकता को ही लागू होता है अगर उपरोक्त शर्तों में से कोई भी मुलाकात कर रहे हैं, और उन शर्तों में से एक क्रम मूल्य पर निर्भर करता है।
बेशक, कुछ मामलों में संकलक सकारात्मक रूप से निर्धारित कर सकता है कि इनपुट ठीक से नहीं हो सकता है (उदाहरण के लिए, जब यह this
पॉइंटर है), लेकिन मुझे अभी भी लगता है कि संकलक कोड को अस्वीकार नहीं कर सकता है जब तक कि यह निर्धारित नहीं हो जाता कथन पूरा हो जाएगा (आमतौर पर एक रन-टाइम प्रश्न)।
एक चेतावनी निदान यहां निश्चित रूप से मूल्यवान है, लेकिन क्या यह संकलक के लिए इस कोड को अस्वीकार करने के लिए मानक-अनुरूप है?
6. बहुत अधिक क्रिस्टल स्पष्ट है, है ना? विशेष रूप से उपरोक्त सब कुछ लागू नहीं होता है। –
@AlexandreC .: दिखाए गए कोड से आप कैसे बता सकते हैं, कि (4) लागू नहीं होता है? ध्यान दें कि यह "शून्य सूचक * मान *" कहता है, जो रनटाइम तक ज्ञात नहीं हो सकता है, न कि "शून्य सूचक * शाब्दिक *" या "शून्य सूचक * स्थिर *"। –
(मैं डाउनवॉटर नहीं हूं)। दरअसल, मैंने इन पंक्तियों के साथ "शून्य सूचक 'शाब्दिक' या कुछ पढ़ा। क्या आप यह इंगित करने की कोशिश कर रहे हैं कि संकलक को डायनामिक कास्ट को 'assert (! V)' या गैर पॉलिमॉर्फिक मामले में समान कुछ में अनुवाद करना चाहिए? –