views:

78

answers:

3

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;
+2  A: 

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.

DeadMG
+2  A: 
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 
} 
James Curran
I used the shortened version because it ensures that ptr is never misused if it's not a Derived1. If the OP is not an experienced C++ coder, this is an additional level of protection.
DeadMG
A: 

You could use RTTI (typeid and dynamic_cast), or add a virtual function that, in the implementation, identifies the class (rolling your own RTTI).

Generally, if you can avoid it, it is considered bad practice to add implementation-dependent code (code that cares what the exact type is) except for in the implementation itself. By "implementation", I don't just mean the specific derives class, I also mean paired/related classes that are specific to that implementation.

Try to roll the switch/else-if statements that are specific to your exact implementations into the implementations themselves, via polymorphism.

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

Merlyn Morgan-Graham