2010-07-23 26 views
6

की एक सरणी का उपयोग करते समय कौन सी व्युत्पन्न कक्षा को इंगित किया जा रहा है यह निर्धारित करने के लिए कि मैं एक सी ++ प्रोग्राम लिख रहा हूं जो एक मर जाएगा और एक सिक्का फ्लिप करेगा। मुझे विरासत और बहुरूपता का उपयोग करने की आवश्यकता है। मेरे पास वर्चुअल फ़ंक्शंस सही तरीके से सेट हैं। मेरी बेस क्लास (aRandomNumberGenerator) में मेरे पास वर्चुअल फ़ंक्शन उत्पन्न होता है। मुख्य() में मुझे अपने व्युत्पन्न वर्गों (एडी और एकोइन) में 2 बेस क्लास पॉइंटर्स की एक सरणी की आवश्यकता है। जब मैं जेनरेट() फ़ंक्शन को कॉल करता हूं तो मुझे कैसे पता चलेगा कि किस व्युत्पन्न वर्ग को सरणी में इंगित किया जा रहा है ??पॉइंटर्स

कोड:

int main() 
{ 
    int n; 
    int frequency1 = 0; // count of 1s rolled 
    int frequency2 = 0; // count of 2s rolled 
    int frequency3 = 0; // count of 3s rolled 
    int frequency4 = 0; // count of 4s rolled 
    int frequency5 = 0; // count of 5s rolled 
    int frequency6 = 0; // count of 6s rolled 
    int face; // stores most recently rolled value 
    int numHeads = 0; // count of heads 
    int numTails = 0; // count of tails 
    int side; // stores most recently flipped value 

    cout << "Enter a seed number: "; // promp for user to enter a seed number 
    cin >> n; 
    cout << endl; 
    cout << endl; 

    aRandomNumberGenerator number(n); 
    aDie die(n, n); 
    aCoin coin(n, n); 

    aRandomNumberGenerator *games[2]; // array of 2 base class pointers 

    for(int i=0; i <= 2; i++) 
     games[i]->generate(); 


    // output the seed number entered by the user 
    cout << "the seed entered is: " << die.inputSeed(n) << endl; 
    cout << endl; 
    cout << endl; 

    // summarize results for 600 flips of a coin 
    for(int counter2 = 0; counter2 < 600; counter2++) 
    { 
     side = generate(); 

     // determine flip value 0/1 and increment appropriate counter 
     switch (side) 
     { 
     case 0: 
      ++numHeads; 
      break; 
     case 1: 
      ++numTails; 
      break; 
     default: 
      cout << "can only be heads or tails"; 
     } 
    } 

    // summarize results for 600 rolls of a die 
    for(int counter1 = 0; counter1 < 600; counter1++) 
    { 
     face = generate(); 

     // determine roll value 1-6 and increment appropriate counter 
     switch (face) 
     { 
     case 1: 
      ++frequency1; 
      break; 
     case 2: 
      ++frequency2; 
      break; 
     case 3: 
      ++frequency3; 
      break; 
     case 4: 
      ++frequency4; 
      break; 
     case 5: 
      ++frequency5; 
      break; 
     case 6: 
      ++frequency6; 
      break; 
     default: 
      cout << "7 doen't exist on a die!"; 
     } 
    } 

    // output results 
    cout << "Heads: " << numHeads << endl; 
    cout << "Tails: " << numTails << endl; 
    cout << "1: " << frequency1 << endl; 
    cout << "2: " << frequency2 << endl; 
    cout << "3: " << frequency3 << endl; 
    cout << "4: " << frequency4 << endl; 
    cout << "5: " << frequency5 << endl; 
    cout << "6: " << frequency6 << endl; 

    cout << endl; 
    cout << endl; 
    system ("pause"); 
    return 0; 
+3

पूरे मुद्दे of.using बहुरूपता कि Hou प्रकार सभी –

उत्तर

8

उपयोग dynamic_cast।

if (Derived1* ptr = dynamic_cast<Derived1*>(basepointer)) { 
    // Do something with ptr 
} 

हालांकि नियमित विधि कॉल के लिए आपको इसे निर्धारित करने की आवश्यकता नहीं है। बस बेस क्लास पर विधि को कॉल करें और इसे सही व्युत्पन्न वर्ग में भेजा जाएगा- यही वह विरासत है जिसके लिए विरासत है।

संपादित करें: नियमित वर्चुअल विधि के लिए, आप इसे केवल मूल सूचक पर कॉल कर सकते हैं और व्युत्पन्न क्या है या नहीं जानते हैं, और आपको सही फ़ंक्शन कॉल मिल जाएगी।

3
aRandomNumberGenerator *games[2]; // array of 2 base class pointers 

for(int i=0; i <= 2; i++) 
    games[i]->generate(); 

सबसे पहले, हम अन्य चीजों से निपटने से पहले इसे काम करते हैं।

आप एक सरणी बना रहे हैं जो पॉइंटर्स को दो aRandomNumberGenerator ऑब्जेक्ट्स पर रखेगा, लेकिन आप कभी भी aRandomNumberGenerator ऑब्जेक्ट्स स्वयं नहीं बनाते। games[0] और games[1] अर्थहीन मान रखें। इसके अलावा, लूप में, आप games[2] तक भी पहुंच सकते हैं जो मौजूद नहीं है।

अद्यतन: किसी कारण से, अन्य उत्तरदाता ने कोड के विचित्र शॉर्टेंड संस्करण का उपयोग करने का निर्णय लिया, जिसे मैं नफरत करता हूं, और शायद किसी भी अनुभवहीन सी ++ कोड (जिसे ओपी स्पष्ट रूप से है) को भ्रमित कर देगा, तो चलो अपने आप को:

Derived1* ptr = dynamic_cast<Derived1*>(basepointer) 
if (ptr != null) 
{ 
    // Do something with ptr 
} 
+0

पर मैं अपने पाश के लिए निर्धारित के बारे में to.worry की जरूरत नहीं है, मैं सामान्य वस्तुओं की तरह प्रत्येक वस्तु बनाने के लिए की जरूरत है है? और इसके लिए गतिशील_कास्ट कोड क्या है? पूर्व। aRandomNumberGenerator games [0] = और aCoin aRandomNumberGenerator games [1] = और aDie – user400586

+0

मैंने संक्षिप्त संस्करण का उपयोग किया क्योंकि यह सुनिश्चित करता है कि यदि कोई व्युत्पन्न नहीं है तो पीआरटी का कभी दुरुपयोग नहीं किया जाता है। यदि ओपी अनुभवी सी ++ कोडर नहीं है, तो यह सुरक्षा का एक अतिरिक्त स्तर है। – Puppy

0

आप RTTI (typeid और dynamic_cast) का उपयोग करें, या एक आभासी समारोह है कि, कार्यान्वयन में, वर्ग (अपनी खुद की RTTI रोलिंग) को दिखाता है जोड़ सकते हैं।

आम तौर पर, यदि आप इससे बच सकते हैं, तो इसे कार्यान्वयन में निर्भर करने के अलावा कार्यान्वयन-निर्भर कोड (कोड जो सटीक प्रकार की परवाह करता है) जोड़ने के लिए बुरा अभ्यास माना जाता है। "कार्यान्वयन" के द्वारा, मेरा मतलब सिर्फ विशिष्ट व्युत्पन्न वर्ग का नहीं है, मेरा मतलब है कि उस कार्यान्वयन के लिए विशिष्ट जोड़ी/संबंधित कक्षाएं हैं।

स्विच/अन्य-रोल को रोल करने का प्रयास करें, जो कि पॉलिमॉर्फिज्म के माध्यम से कार्यान्वयन में आपके सटीक कार्यान्वयन के लिए विशिष्ट हैं।

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.6

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