2011-06-11 19 views
7

मैं भाग का उपयोग करने के लिए एक वस्तु एक अलग तरीके से व्यवहार किया जाता है, जहां पदानुक्रम में यह गिर जाता है पर निर्भर करता है करना चाहते हैंसी ++ अधिभार संकल्प

(similar to this C# question)

मान लें आप की तरह आकार वस्तुओं की एक पदानुक्रम का निर्माण:

class Ray 
{ 
    Intersection intersects(const Sphere * s) ; 
    Intersection intersects(const Triangle * t) ; 
}; 
:
class Shape {} ; 
class Sphere : public Shape {} ; 
class Triangle : public Shape {} ; ... 

फिर आप की तरह के तरीकों के साथ एक रे वर्ग से लैस नहीं कर सकते हैं:

आप विभिन्न प्रकार के मिश्रित आकार * की एक सरणी की दुकान और फोन

vector<Shape*> shapes ; ... 
//foreach shape.. 
Intersection int = ray.intersects(shapes[ i ]) 

लेकिन तुम संकलक त्रुटि

त्रुटि C2664 मिलती है: 'चौराहे रे :: intersects (स्थिरांक क्षेत्र *) स्थिरांक' करने के लिए 'आकार * स्थिरांक' से पैरामीटर 1 कन्वर्ट 'स्थिरांक क्षेत्र *'

क्या तुम गलत क्या किया?

साथ

class Shape 
{ 
    virtual Intersection intersects(const Ray* ray)=0 ; 
} ; 

तो प्रत्येक वर्ग ओवरराइड काटती है यह अन्य चारों ओर जिस तरह से करने के लिए एक ही रास्ता है? तब

//foreach shape.. 
Intersection int = shapes[i]->intersects(ray) ; 

करने के लिए कॉल आप यह पहली तरह से मैं पता चला है या कभी नहीं कर सकता हूँ?

+1

मुझे लगता है कि [एकाधिक (डबल) प्रेषण] (http://en.wikipedia.org/wiki/Multiple_dispatch) है। सी ++ में यह मूल रूप से नहीं है। –

+0

[विरासत हमेशा सही नहीं है।] (Http: //en.wikipedia।संगठन/विकी/सर्कल-एलीपसे_प्रोबलेम) –

उत्तर

4

आप इसे दूसरी तरह के आसपास क्या करना है। अधिभार संकल्प संकलन समय में होता है, जब क्या आप इसके साथ कॉल कर रहे हैं के प्रकार के एक Shape* है।

4

नहीं, आप यह पहला रास्ता नहीं कर सकते। सी ++ में अधिभार संकल्प समारोह तर्कों की स्थिर प्रकार पर आधारित है। यह संकलन समय पर हल किया गया है। अपने उदाहरण में स्थिर प्रकार Shape * है और वहाँ अपनी कक्षा में कोई समारोह है कि एक Shape * (इसलिए त्रुटि) को स्वीकार करेंगे है। कंपाइलर परवाह नहीं है कि आपका पॉइंटर वास्तव में रन समय पर Sphere पर इंगित कर सकता है।

लागू करने के लिए क्या आप को लागू करने की आपके पास करने के लिए कोशिश कर रहे हैं "चैनल" एक सुविधा है कि आभासी समारोह कॉल के माध्यम से वस्तुओं की गतिशील प्रकार, अर्थात् पर निर्भर करता है, है जो आप अपने दूसरे उदाहरण में कर के माध्यम से अपने कॉल।

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

0

हो सकता है आप इसे आरटीटीआई जानकारी के साथ खींच सकते हैं। मैंने यह नहीं किया है लेकिन यह संभव हो सकता है।

class Ray 
{ 
    Intersection intersects(const Sphere * s) ; 
    Intersection intersects(const Triangle * t) ; 
    Intersection intersects(const Shape * s) { 
     //act on RTTI info, or 
     //use dynamic_cast to other types and check if the result is NULL or not 
    } 
}; 
+0

हां, मुझे 'टाइपिड()' के बारे में पता है, लेकिन निश्चित रूप से मैं उस – bobobobo

+1

का उपयोग करने से बचना चाहता हूं तो उत्तर लगभग निश्चित रूप से नहीं है। –

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