2010-07-16 18 views
7

मैंने विज़िटर पैटर्न को अनुसरण के रूप में लिखा है लेकिन मुझे समझ में नहीं आता कि सिंगल और डबल डिस्पैच क्या है। AFAIK, एकल प्रेषण कॉलर प्रकार के आधार पर एक विधि का आह्वान करता है जहां डबल प्रेषण कॉलर प्रकार और तर्क प्रकार के आधार पर एक विधि का आह्वान करता है।सिंगल और डबल डिस्पैच क्या है?

मुझे लगता है कि सिंगल क्लास पदानुक्रम में डबल प्रेषण होता है लेकिन क्यों विज़िटर क्लास में दो वर्ग पदानुक्रम होते हैं लेकिन इसे अभी भी डबल प्रेषण के रूप में माना जाता है।

void floppyDisk::accept(equipmentVisitor* visitor) 
{ 
visitor->visitFloppyDisk(this); 
} 

void processor::accept(equipmentVisitor* visitor) 
{ 
visitor->visitProcessor(this); 
} 

void computer::accept(equipmentVisitor* visitor) 
{ 
BOOST_FOREACH(equipment* anEquip, cont) 
{ 
    anEquip->accept(visitor); 
} 

visitor->visitComputer(this); 
} 

void visitFloppyDisk(floppyDisk*); 
void visitProcessor(processor*); 
void visitComputer(computer*); 

कृपया प्रदान किए गए उदाहरण कोड का उपयोग करके समझाएं।

AFAIK, पहला प्रेषण उस ऑब्जेक्ट पर होता है जो स्वीकृति का आह्वान करता है और दूसरा प्रेषण विज़िट विधि का आह्वान करने वाले ऑब्जेक्ट पर होता है।

धन्यवाद।

+0

हो सकता है कि पढ़ने इस [लेख ] (http://en.wikipedia.org/wiki/Multiple_dispatch) प्रेषण को समझने में आपकी सहायता कर सकता है - यह C++ में कैसे कार्यान्वित किया गया है, लेकिन अवधारणा –

उत्तर

9

संक्षेप में, एकल प्रेषण तब होता है जब एक विधि एक पैरामीटर के प्रकार पर पॉलिमॉर्फिक होता है (अंतर्निहित this सहित)। दो प्रेषणों पर डबल प्रेषण polymorphism है।

पहले के लिए सामान्य उदाहरण मानक वर्चुअल विधि है, जो कि ऑब्जेक्ट के प्रकार पर पॉलिमॉर्फिक है। और दूसरा व्यक्ति आगंतुक पैटर्न के माध्यम से लागू किया जा सकता है।

[अद्यतन] मुझे लगता है कि अपने उदाहरण में, floppyDisk, processor और computer प्रत्येक एक आम आधार वर्ग जो एक आभासी विधि के रूप में परिभाषित करता है accept से विरासत। इसी तरह, visit* विधियों को equipmentVisitor में वर्चुअल घोषित किया जाना चाहिए, जिसमें कुछ visit* कार्यान्वयन के साथ कुछ व्युत्पन्न कक्षाएं होनी चाहिए। [/ अद्यतन]

ऊपर मानते हुए, acceptthis और equipmentVisitor दोनों पर बहुरूपी है। फ्लॉपीडिस्क, प्रोसेसर और कंप्यूटर प्रत्येक के पास accept का अपना कार्यान्वयन होता है, इसलिए जब विज़िटर accept पर कॉल करता है, तो कैली को कैली के प्रकार के आधार पर प्रेषित किया जाता है। फिर कैली विज़िटर के विशिष्ट विज़िट विज़िट विधि को वापस कॉल करता है, और यह कॉल विज़िटर के वास्तविक प्रकार के आधार पर प्रेषित किया जाता है।

सिद्धांत रूप में वहाँ ट्रिपल हो सकता है, चौगुनी आदि भी प्रेषण, हालांकि मैं इस (व्यवहार में लागू किया भाषाओं में है कि प्रकृति के द्वारा दोहरे और उच्च डिस्पैच का समर्थन नहीं करते कभी नहीं देखा है, वह यह है कि - मुझे लगता है कि स्मालटाक याद करने लगते हैं कर देता है?)। सी ++ में विज़िटर का उपयोग करके डबल प्रेषण और इसी तरह की भाषाओं में पहले से ही काफी दिमाग-दबदबा है, इसलिए ट्रिपल और उच्च प्रेषण के कार्यान्वयन को वास्तविक अनुप्रयोगों में उपयोग करने के लिए बहुत जटिल हो जाएगा।

+1

+1, उन भाषाओं में एकाधिक प्रेषण जो मूल रूप से इसका समर्थन नहीं करते हैं writting सभी संयोजन, और जो प्रेषण के लिए तर्कों की संख्या के साथ तेजी से बढ़ता है, जो इसे टालने का प्रयास करने का एक अच्छा कारण है। –

6

आपके उदाहरण में, आप तंत्र की मूल बातें खो रहे हैं: विरासत और गुणधारा। के अपने कोड के अलावा निम्नलिखित वर्ग पदानुक्रम मान, चलो: अब

class equipmentVisited 
{ 
    virtual void accept(equipmentVisitor* visitor) = 0; 
} 

class floppyDisk : public equipmentVisited 
{ 
    virtual void accept(equipmentVisitor* visitor); 
} 

class processor : public equipmentVisited 
{ 
    virtual void accept(equipmentVisitor* visitor); 
} 

class computer : public equipmentVisited 
{ 
    virtual void accept(equipmentVisitor* visitor); 
} 

class equipmentVisitor 
{ 
    virtual void visitFloppyDisk(floppyDisk*); 
    virtual void visitProcessor(processor*); 
    virtual void visitComputer(computer*); 
} 

// Some additional classes inheriting from equipmentVisitor would be here 

, कल्पना करें कि आप कुछ समारोह में कोड के इस टुकड़े है:

equipmentVisited* visited; 
equipmentVisitor* visitor; 
// ... 
// Here you initialise visited and visitor in any convenient way 
// ... 
visited->accept(visitor); 

डबल प्रेषण तंत्र के लिए धन्यवाद, यह अंतिम पंक्ति किसी भी equipmentVisited को किसी भी equipmentVisitor को स्वीकार करने की अनुमति देता है, इससे कोई फर्क नहीं पड़ता कि उनके वास्तविक स्थिर प्रकार क्या हैं। आखिरकार, सही कार्य को सही वर्ग के लिए बुलाया जाएगा।

संक्षेप में:

  • पहले प्रेषण उचित वर्ग
  • दूसरा प्रेषण पहले प्रेषण द्वारा चयनित वर्ग पर उचित फ़ंक्शन को कॉल करने पर accept() कॉल
संबंधित मुद्दे