2010-07-23 19 views
6

J'écris un programme C++ qui va lancer un dé et retourner une pièce. J'ai besoin d'utiliser l'héritage et le polymorphisme. J'ai mes fonctions virtuelles configurées correctement. Dans ma classe de base (aRandomNumberGenerator) j'ai une fonction virtuelle générer. Dans main(), j'ai besoin d'un tableau de 2 pointeurs de classe de base pour mes classes dérivées (aDie et aCoin). Comment puis-je savoir quelle classe dérivée est pointée dans le tableau lorsque j'appelle la fonction generate() ??Comment déterminer quelle classe dérivée est pointée lors de l'utilisation d'un tableau de pointeurs

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; 
+3

Le polymorphisme of.using point entier est que hou n'ont pas to.worry sur le type du tout –

Répondre

8

Utilisez dynamic_cast. Cependant, pour un appel de méthode ordinaire, vous n'avez pas besoin de le déterminer. Appelez simplement la méthode sur la classe de base et elle sera envoyée à la classe dérivée correcte - c'est ce que l'héritage est pour. Editer: Pour une méthode virtuelle régulière, vous pouvez simplement l'appeler sur le pointeur de base et ne pas savoir ou se soucier de ce qu'est le Dérivé, et vous obtiendrez le bon appel de fonction.

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

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

D'abord, passons à l'action avant de faire autre chose.

Vous créez un tableau qui contient des pointeurs vers deux objets aRandomNumberGenerator, mais vous ne créez jamais eux-mêmes les objets aRandomNumberGenerator. games[0] et games[1] maintiennent des valeurs sans signification. De plus, dans la boucle, vous avez également accès à games[2] qui n'existe pas. Pour une raison quelconque, l'autre répondeur a décidé d'utiliser la version sténographique bizarre du code, que je déteste, et qui confondrait probablement tout code C++ inexpérimenté (ce que l'OP est clairement), alors faisons-le nous:

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

je fixe ma boucle, dois-je créer chaque objet comme des objets normaux? et aussi à quoi sert le code dynamic_cast? ex. aRandomNumberGenerator games [0] = & aCoin aRandomNumberGenerator games [1] = & aDie – user400586

+0

J'ai utilisé la version raccourcie car elle garantit que ptr n'est jamais mal utilisé s'il ne s'agit pas d'un Derived1. Si l'OP n'est pas un codeur C++ expérimenté, il s'agit d'un niveau de protection supplémentaire. – Puppy

0

Vous pouvez utiliser RTTI (typeid et dynamic_cast), ou ajouter une fonction virtuelle qui, dans la mise en œuvre, identifie la classe (rouler votre propre RTTI).

Généralement, si vous pouvez l'éviter, il est considéré comme une mauvaise pratique d'ajouter du code dépendant de l'implémentation (code qui se soucie du type exact) sauf dans l'implémentation elle-même. Par "implémentation", je ne parle pas seulement de la classe dérivée spécifique, mais aussi des classes liées/liées qui sont spécifiques à cette implémentation. Essayez de lancer les instructions switch/else-if spécifiques à vos implémentations exactes dans les implémentations elles-mêmes, via le polymorphisme.

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