9

में डबल प्रेषण/बहुआयामी I C++ डबल प्रेषण पर एक प्रश्न है। नीचे दिए गए कोड में, मैं दूसरे सेट से परिणामों को पहले सेट से परिणामों से मेल खाने के लिए चाहता हूं।सी ++

मैं वास्तविक प्रकार पता नहीं (जब तक मैं dynamic_cast कोशिश), लेकिन मैं जानता हूँ कि है कि वस्तु BaseClass प्रकार से विरासत में मिली। इसे पूरा करने के लिए सबसे कुशल (प्रदर्शन-वार) तरीका क्या है?

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

किसी भी मदद के लिए धन्यवाद।

#include <iostream> 
#include <string> 
using namespace std; 

class BaseClass{ 
public: 
     BaseClass(){} 
     virtual void myFunction(){cout << "base myFunction called" << endl;} 
}; 

class Derived1: public BaseClass{ 
public: 
     Derived1():BaseClass(){} 
     void myFunction(){cout << "Derived1 myFunction called" << endl;} 
}; 


class Derived2: public BaseClass{ 
public: 
     Derived2():BaseClass(){} 
     void myFunction(){cout << "Derived2 myFunction called" << endl;} 
}; 

class Derived3: public BaseClass{ 
public: 
     Derived3():BaseClass(){} 
     void myFunction(){cout << "Derived3 myFunction called" << endl;} 

}; 

class Processor{ 
public: 
     Processor(){} 
     virtual void processObj(BaseClass* bc){cout << "got a base object" << endl; bc->myFunction();} 
     virtual void processObj(Derived1* d1){cout << "got a derived1 object" << endl; d1->myFunction();} 
     virtual void processObj(Derived2* d2){cout << "got a derived2 object" << endl; d2->myFunction(); } 
}; 


int main() { 
    BaseClass *bcp=new BaseClass(); 
    Derived1 *dc1p=new Derived1(); 
    Derived2 *dc2p=new Derived2(); 
    Derived3 *dc3p=new Derived3(); 

    Processor p;//can also use Processor* p = new Processor() 

    //first set results 
    p.processObj(bcp); 
    p.processObj(dc1p); 
    p.processObj(dc2p); 
    p.processObj(dc3p); 

    BaseClass *bcp1=bcp; 
    BaseClass *dc1p1=dc1p; 
    BaseClass *dc2p1=dc2p; 
    BaseClass *dc3p1=dc3p; 

    //second set results 
    p.processObj(bcp1); 
    p.processObj(dc1p1); 
    p.processObj(dc2p1); 
    p.processObj(dc3p1); 

    return 0; 
} 
+0

... कोड को कोड ब्लॉक में एम्बेड करने के लिए संपादित किया गया –

उत्तर

4

आपको व्युत्पन्न कक्षाओं से प्रक्रिया ओबीजे को कॉल करने के लिए बेस क्लास पर वर्चुअल विधि डालना होगा।

class BaseClass{ 
public: 
     BaseClass(){} 
     virtual void ProcessThis(Processor &p) { p.processObj(this); } 
     virtual void myFunction(){cout << "base myFunction called" << endl;} 
}; 

class Derived1: public BaseClass{ 
public: 
     Derived1():BaseClass(){} 
     void ProcessThis(Processor &p) { p.processObj(this); } 
     void myFunction(){cout << "Derived1 myFunction called" << endl;} 
}; 

class Derived2: public BaseClass{ 
public: 
     Derived2():BaseClass(){} 
     void ProcessThis(Processor &p) { p.processObj(this); } 
     void myFunction(){cout << "Derived2 myFunction called" << endl;} 
}; 

class Derived3: public BaseClass{ 
public: 
     Derived3():BaseClass(){} 
     void ProcessThis(Processor &p) { p.processObj(this); } 
     void myFunction(){cout << "Derived3 myFunction called" << endl;} 

}; 

class Processor{ 
public: 
     Processor(){} 
     virtual void processObj(BaseClass* bc){cout << "got a base object" << endl; bc->myFunction();} 
     virtual void processObj(Derived1* d1){cout << "got a derived1 object" << endl; d1->myFunction();} 
     virtual void processObj(Derived2* d2){cout << "got a derived2 object" << endl; d2->myFunction(); } 
}; 

int main() { 
    BaseClass *bcp=new BaseClass(); 
    Derived1 *dc1p=new Derived1(); 
    Derived2 *dc2p=new Derived2(); 
    Derived3 *dc3p=new Derived3(); 

    Processor p;//can also use Processor* p = new Processor() 

    //first set results 
    bcp->ProcessThis(p); 
    dc1p->ProcessThis(p); 
    dc1p->ProcessThis(p); 
    dc3p->ProcessThis(p); 

    BaseClass *bcp1=bcp; 
    BaseClass *dc1p1=dc1p; 
    BaseClass *dc2p1=dc2p; 
    BaseClass *dc3p1=dc3p; 

    //second set results 
    bcp1->ProcessThis(p); 
    dc1p1->ProcessThis(p); 
    dc2p1->ProcessThis(p); 
    dc3p1->ProcessThis(p); 

    Processor p2; 
    bcp1->ProcessThis(p2); 
    dc1p1->ProcessThis(p2); 
    dc2p1->ProcessThis(p2); 
    dc3p1->ProcessThis(p2); 

    return 0; 
} 

आप मूल रूप से विज़िटर पैटर्न चाहते हैं, लेकिन केवल एक ही प्रकार के विज़िटर के साथ। आप अपने आप को कुछ भविष्य के प्रयासों को बचा सकते हैं और प्रोसेसर को एक अमूर्त वर्ग में बना सकते हैं और एक कंक्रीट प्रोसेसर इंपल क्लास को कार्यान्वित कर सकते हैं, जिससे भविष्य में एक और प्रोसेसर क्लास जोड़ने में मुश्किल हो सकती है, या आप तब तक इंतजार कर सकते हैं जब तक कि स्थिति आती है और चीजों को छोड़ दें ।

6

Visitor Pattern सिर्फ स्थिति इस तरह की से निपटने के लिए बनाया गया है।

10

आप डबल प्रेषण की "डबल" भाग याद किया। विधि है कि सही प्रकार स्वीकार करता है -

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

संक्षेप में, प्रत्येक ऑब्जेक्ट को वर्चुअल processMe(Processor &p) विधि की आवश्यकता होती है, और प्रोसेसर इसे कॉल करता है। processMe का कार्यान्वयन p.processObject(this) पर कॉल करता है। लेकिन इस बार चारों ओर, "यह" एक ज्ञात प्रकार है! तो अनंत रिकर्सन के बजाय, आप proceessObject को

0

के साथ समाप्त करने के लिए सही है। इससे मेरी समस्या हल हो गई और मैं समझता हूं कि डबल प्रेषण का मतलब क्या है! यहां पोस्टरिटी के लिए पूरा कोड दिया गया है (कोई मुझे कृपया प्रारूपण को सही तरीके से कैसे प्राप्त करें):

#include <iostream> 
using namespace std; 

class BaseClass; 
class Derived1; 
class Derived2; 
class Derived3; 

class Processor { 
public: 
     Processor(){} 
     virtual void processObj(BaseClass* bc); 
     virtual void processObj(Derived1* d1); 
     virtual void processObj(Derived2* d2); 
}; 


class BaseClass{ 
public: 
     BaseClass(){} 
     virtual void ProcessThis(Processor &p) { p.processObj(this); } 
     virtual void myFunction(){cout << "base myFunction called" << endl;} 
}; 

class Derived1: public BaseClass{ 
public: 
     Derived1():BaseClass(){} 
     void ProcessThis(Processor &p) { p.processObj(this); } 
     void myFunction(){cout << "Derived1 myFunction called" << endl;} 
}; 

class Derived2: public BaseClass{ 
public: 
     Derived2():BaseClass(){} 
     void ProcessThis(Processor &p) { p.processObj(this); } 
     void myFunction(){cout << "Derived2 myFunction called" << endl;} 
}; 

class Derived3: public BaseClass{ 
public: 
     Derived3():BaseClass(){} 
     void ProcessThis(Processor &p) { p.processObj(this); } 
     void myFunction(){cout << "Derived3 myFunction called" << endl;} 

}; 

void Processor::processObj(BaseClass* bc){cout << "got a base object" << endl; bc->myFunction();} 
void Processor::processObj(Derived1* d1){cout << "got a derived1 object" << endl; d1->myFunction();} 
void Processor::processObj(Derived2* d2){cout << "got a derived2 object" << endl; d2->myFunction(); } 


int main() { 
    BaseClass *bcp=new BaseClass(); 
    Derived1 *dc1p=new Derived1(); 
    Derived2 *dc2p=new Derived2(); 
    Derived3 *dc3p=new Derived3(); 

    Processor p;//can also use Processor* p = new Processor() 

    //first set results 

    bcp->ProcessThis(p); 
    dc1p->ProcessThis(p); 
    dc2p->ProcessThis(p); 
    dc3p->ProcessThis(p); 

    BaseClass *bcp1=bcp; 
    BaseClass *dc1p1=dc1p; 
    BaseClass *dc2p1=dc2p; 
    BaseClass *dc3p1=dc3p; 

    //second set results 

    bcp1->ProcessThis(p); 
    dc1p1->ProcessThis(p); 
    dc2p1->ProcessThis(p); 
    dc3p1->ProcessThis(p); 

    Processor p2; 
    bcp1->ProcessThis(p2); 
    dc1p1->ProcessThis(p2); 
    dc2p1->ProcessThis(p2); 
    dc3p1->ProcessThis(p2); 

    return 0; 
}