2012-08-07 13 views
11

मैं अपने आधार वर्ग के रूप में निम्नानुसार है:सी ++ विरासत downcasting

class point //concrete class 
{ 
... //implementation 
} 

class subpoint : public point //concrete class 
{ 
...  //implementation 
} 

कैसे मैं एक subpoint वस्तु के लिए एक बिंदु वस्तु से डाली हैं? मैंने निम्नलिखित तीनों को आजमाया है:

point a; 
subpoint* b = dynamic_cast<subpoint*>(&a); 
subpoint* b = (subpoint*)a; 
subpoint b = (subpoint)a; 

इन जानवरों के साथ क्या गलत है?

उत्तर

22

मैं पॉइंट ऑब्जेक्ट से उप-ऑब्जेक्ट ऑब्जेक्ट में कैसे डालूं?

आप नहीं कर सकते; जब तक कि point में एक रूपांतरण ऑपरेटर नहीं है, या subpoint में एक रूपांतरण कन्स्ट्रक्टर है, जिस स्थिति में ऑब्जेक्ट प्रकारों को कास्ट की आवश्यकता के बिना परिवर्तित किया जा सकता है।

आप एक pointसंदर्भ (या सूचक) एक subpointसंदर्भ (या सूचक) से डाली सकता है अगर संदर्भित किया जाता ऑब्जेक्ट प्रकार subpoint की वास्तव में थे:

subpoint s; 

point & a = s; 
subpoint & b1 = static_cast<subpoint&>(a); 
subpoint & b2 = dynamic_cast<subpoint&>(a); 

पहले (static_cast) अधिक खतरनाक है; कोई जांच नहीं है कि रूपांतरण मान्य है, इसलिए asubpoint का संदर्भ नहीं देता है, तो b1 का उपयोग अपरिभाषित व्यवहार होगा।

दूसरा (dynamic_cast) सुरक्षित है, लेकिन केवल तभी काम करेगा यदि point पॉलिमॉर्फिक है (यानी, यदि यह वर्चुअल फ़ंक्शन है)। यदि a असंगत प्रकार की वस्तु को संदर्भित करता है, तो यह अपवाद फेंक देगा।

+0

ऑब्जेक्ट जो कि डाला जाएगा वास्तव में प्रकार उप-बिंदु है, यह केवल बिंदुओं की एक श्रृंखला में है। – CodeKingPlusPlus

0

asubpoint में नहीं बनाया जा सकता है। वह कार्यान्वयन वहां नहीं है।

0

इन जानवरों के साथ क्या गलत है?

तथ्य यह है कि आप उन्हें करने का प्रयास करते हैं। pointsubpoint नहीं है, अगर यह काम करता है तो मुझे आश्चर्य होगा।

1

कुल मिलाकर, यह काम नहीं करेगा क्योंकि pointsubpoint नहीं है; केवल विपरीत है। हालांकि, अन्य मुद्दे भी हैं।

आदेश में:


subpoint* b = dynamic_cast<subpoint*>(&a); 

dynamic_cast केवल, बहुरूपी प्रकार पर काम करता है जैसे कि, प्रकार है कि कम से कम एक आभासी समारोह की घोषणा। मेरा अनुमान है कि point में कोई वर्चुअल फ़ंक्शन नहीं है, जिसका अर्थ है कि इसका उपयोग dynamic_cast के साथ नहीं किया जा सकता है।


subpoint* b = (subpoint*)a; 

काम करने के लिए इस कलाकारों के लिए, point जरूरतों subpoint * में रूपांतरण ऑपरेटर घोषित करने के लिए, उदाहरण के लिए, point::operator subpoint *()


subpoint b = (subpoint)a; 

इस डाली काम करने के लिए, बिंदु एक निर्माता कि point से एक पैरामीटर convertable लेता है करने के लिए subpointयाsubpoint आवश्यकताओं के एक रूपांतरण ऑपरेटर की घोषणा करने की जरूरत है।

2

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

दूसरा उदाहरण के लिए आप a के बजाय &a की जरूरत है, लेकिन एक बार आप ठीक करने के बाद कि आप अपरिभाषित व्यवहार मिलेगा क्योंकि ऑब्जेक्ट प्रकार गलत है।

तीसरे उदाहरण को प्रतिलिपि बनाते समय रूपांतरण करने के लिए point में operator subpoint() विधि की आवश्यकता होती है।

+1

@MooingDuck, परिभाषित "काम नहीं करेगा?" इसे एक नल पॉइंटर वापस करना चाहिए, जो अपेक्षित नतीजे नहीं हो सकता है लेकिन यह संकलित करता है और कुछ उपयोगी करता है। –

+0

मुझे आपके उत्तर को गलत तरीके से पढ़ना होगा, यह अब मुझे ठीक लग रहा है। –

1

गतिशील कास्ट का उद्देश्य "किसी ऑब्जेक्ट को पदानुक्रम में किसी निश्चित प्रकार का होने पर रन टाइम पर जांचना" है। तो अब देखते हैं कि आपके पास क्या है:

  1. आपके पास एक पॉइंट ऑब्जेक्ट है। उप-बिंदु नहीं।
  2. यदि ऑब्जेक्ट उप-बिंदु है तो आप गतिशील कलाकार से पूछ रहे हैं। यह।
  3. क्योंकि यह उप-बिंदु नहीं है, गतिशील_कास्ट विफल रहता है - यह आपको यह बताने का तरीका है कि ऑब्जेक्ट वह प्रकार नहीं है जिसे आप इसे डालने का प्रयास कर रहे हैं।

इसके विपरीत, यह काम किया है जाएगा:

subpoint c; 
point *a = &c; 
subpoint* b = dynamic_cast<subpoint*>(&a); 
subpoint* b = (subpoint*)a; 
संबंधित मुद्दे