मान लीजिए मैं फल का एक समूह है की ओर इशारा:सेब, संतरे, और सबसे व्युत्पन्न C++ वर्ग
class Fruit { ... };
class Apple : public Fruit { ... };
class Orange: public Fruit { ... };
और कुछ बहुरूपी कार्यों कि पर काम कहा फल:
void Eat(Fruit* f, Pesticide* p) { ... }
void Eat(Apple* f, Pesticide* p) { ingest(f,p); }
void Eat(Orange* f, Pesticide* p) { peel(f,p); ingest(f,p); }
ठीक है, इंतजार । वहीं रुक जाओ। इस बिंदु पर ध्यान दें कि कोई भी साधु व्यक्ति फल वर्गों का वर्चुअल सदस्य फ़ंक्शन खाएगा। लेकिन यह एक विकल्प नहीं है, क्योंकि मैं एक साधु व्यक्ति नहीं हूं। इसके अलावा, मैं अपने फल वर्ग के लिए हेडर फ़ाइल में कीटनाशक * नहीं चाहता हूं।
दुःख की बात है मुझे आगे क्या करना करने में सक्षम होना चाहता हूँ वास्तव में है क्या सदस्य कार्य करता है और गतिशील बंधन अनुमति देते हैं:
typedef list<Fruit*> Fruits;
Fruits fs;
...
for(Fruits::iterator i=fs.begin(), e=fs.end(); i!=e; ++i)
Eat(*i);
और ज़ाहिर है, समस्या यह है कि सूचक हम पारित खाने के लिए है() हो जाएगा एक फल *, ऐप्पल * या ऑरेंज * नहीं, इसलिए कुछ भी नहीं खाया जाएगा और हम सभी बहुत भूखे होंगे।
तो क्या मैं वास्तव में इस के बजाय ऐसा करने में सक्षम होना चाहता हूँ:
Eat(MAGIC_CAST_TO_MOST_DERIVED_CLASS(*i));
लेकिन अपने सीमित ज्ञान के लिए, इस तरह के जादू मौजूद नहीं है, संभवतः में छोड़कर:
Eat(*i);
यह है dynamic_cast पर कॉल से भरा एक बड़ा बुरा अगर कथन का रूप।
तो क्या कुछ रन-टाइम जादू है जिसके बारे में मुझे पता नहीं है? या क्या मुझे गतिशील_casts से भरा एक बड़ा बुरा अगर लागू कथन लागू करना चाहिए? या मुझे इसे चूसना चाहिए, इस बारे में सोचना छोड़ दें कि मैं रूबी में इसे कैसे कार्यान्वित करूंगा, और थोड़ी कीटनाशक को अपने फल हेडर में अपना रास्ता बनाने की अनुमति दूंगा?
अद्यतन: बेयर ईट फ़ंक्शंस और कीटनाशक के साथ प्रदूषित बिट के बजाय, मान लीजिए कि मैं सिर्फ फल में खाना नहीं चाहता क्योंकि यह कोई समझ नहीं आता है। एक फल जो जानता है कि खुद को कैसे खाया जाए? धिक्कारना। इसके बजाय मैं फल के प्रत्येक प्रकार के खाने के लिए एक खाओ समारोह के साथ एक भक्षक वर्ग, अलग कोड के साथ की जरूरत है, और इस मामले में कुछ डिफ़ॉल्ट कोड यह एक फल है कि खाने वाले को नहीं पहचानता है:
class Eater
{
public:
void Eat(Apple* f) { wash(); nom(); }
void Eat(Orange* f) { peel(); nom(); }
void Eat(Fruit* f) { nibble(); }
};
...
Eater me;
for(Fruits::iterator i=fs.begin(), e=fs.end(); i!=e; ++i)
me.Eat(*i); //me tarzan! me eat!
लेकिन फिर, यह नहीं करता है काम नहीं करता है, और सी ++ में सीधा समाधान गतिशील_कास्ट को कॉल का एक समूह लगता है।
हालांकि, जैसा कि उत्तर में से एक सुझाव देता है, एक और चालाक समाधान हो सकता है। क्या होगा यदि फलों ने मटरपील() और MustWash() जैसे कार्यों के साथ खाने वालों के लिए महत्वपूर्ण गुणों का खुलासा किया? तो फिर तुम एक भी खाओ() फ़ंक्शन के साथ मिल सकता है ...
अद्यतन: डैनियल Newby बताते हैं कि आगंतुक का उपयोग कर के रूप में भी प्रस्तुत समस्या का हल ... लेकिन यह एक अर्थ शीर्षासन का एक सा की आवश्यकता है (फल :: उपयोग या फल :: beEaten?)।
जबकि मैं कई उत्तरों स्वीकार करना चाहता हूं, मुझे लगता है कि psmears का जवाब वास्तव में भविष्य के पाठकों के लिए सबसे अच्छा है। सबको धन्यवाद।
शायद आपको स्वयं को सैनिटी अस्पताल में देखना चाहिए और सदस्य कार्य करना चाहिए? –
जबकि सी ++ आपको आरटीटीआई के माध्यम से वास्तविक प्रकार की जानकारी दे सकता है, मुझे वास्तविक उपप्रकार में कलाकार को मजबूर करने के किसी भी तरीके से नहीं पता है। – Jherico
मुझे यकीन नहीं है कि आप जो चाहते हैं वह एकाधिक प्रेषण (http://en.wikipedia.org/wiki/Multiple_dispatch) या गतिशील प्रेषण (http://en.wikipedia.org/wiki/Dynamic_dispatch) है। – Juliano