Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine which derived class is being pointed to when using an array of pointers

I am writing a C++ program that will roll a die and flip a coin. I need to use inheritance and polymorphism. I have my virtual functions set up correctly. In my base class(aRandomNumberGenerator) I have a virtual function generate. In main() I need to have an array of 2 base class pointers to my derived classes(aDie and aCoin). How do I know which derived class is being pointed to in the array when I call the generate() function??

code:

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;
like image 668
user400586 Avatar asked Jul 23 '10 19:07

user400586


2 Answers

Use dynamic_cast.

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

However for a regular method call you don't need to determine it. Just call the method on the base class and it'll be dispatched to the correct derived class- that's what inheritance is for.

Edit: For a regular virtual method, you can just call it on the base pointer and don't know or care what the Derived is, and you'll get the right function call.

like image 178
Puppy Avatar answered Nov 15 '22 01:11

Puppy


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

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

First, let's get it working before we deal with other things.

You are creating an array which will hold pointers to two aRandomNumberGenerator objects, but you never create the aRandomNumberGenerator objects themselves. games[0] and games[1] hold meaningless values. Further, in the loop, you also access games[2] which doesn't exist.

UPDATE: For some reason, the other answerer, decided to use the bizarre shorthand version of the code, which I hate, and would probably confuse any inexperienced C++ code (which the OP clearly is), so let's do that ourselves:

Derived1* ptr = dynamic_cast<Derived1*>(basepointer)
if (ptr != null) 
{ 
    // Do something with ptr 
} 
like image 42
James Curran Avatar answered Nov 15 '22 01:11

James Curran