2015-03-04 1 views
0

je traite la classe de base entité, et je veux ses classes dérivées (Player, Enemy, Bullet) d'avoir collideWith() appeléfonctions de classes dérivées ne sont pas appelés

J'ai essayé d'obtenir les fonctions dérivées de travailler, cependant, la version de base est toujours appelée, qui se trouve être vide, même lorsque j'ai supprimé le virtuel mot-clé

classe de base Entité

virtual void collideWith(Entity*); 
    // Right now the derived classes of collideWIth are not being called, 
    // even with the virtual removed 

et sa fonction, qui est collideWith() de l'entité toujours appelé pendant le contrôle de collision

void Entity::collideWith(Entity*){ 

} 

classes dérivées avec fonction collideWith, sans mot-clé virtuel Ce ne sont jamais appelé lors de l'enregistrement de collision

void Player::collideWith(Bullet*) 
void Player::collideWith(Enemy*) 
void Enemy::collideWith(Bullet*) 
void Enemy::collideWith(Player*) 
void Bullet::collideWith(Player*) 
void Bullet::collideWith(Enemy*) 

Fonction pour le contrôle de collisions points de p et q à l'entité * de EntityList, qui contient son dérivé cours joueur, l'ennemi, et Bullet

void SceneGame::checkCollisions(){ 

    populateGrid(); 

    // Right now I am unable to get the collision detection to work! 

    for (auto i = 0; i < gridBox.slicesX; ++i){ 
     for (auto j = 0; j < gridBox.slicesY; ++j){ 
      if (gridBox.cell[i][j].nEntities < 2) continue; 

      for (auto k = 0; k < gridBox.cell[i][j].nEntities; ++k){ 
       for (auto l = 0; l < gridBox.cell[i][j].nEntities; ++l){ 

        // Set up the pointers and compare them 
        auto p = gridBox.cell[i][j].items[k]; 
        auto q = gridBox.cell[i][j].items[l]; 
        if (p == q) continue; // we do not want the same pointer 

        if (p->getGlobalBounds(). 
         intersects(q->getGlobalBounds())){ 

         // Do a series of collisions depending on the specific entities 

         /* 
          However, I end up always calling the BASE function of collideWith 
          instead of the derived types (Player, Enemy, Bullet, etc.) 
         */ 
         p->collideWith(q); 

        } 


       } 
      } 
     } 
    } 

} 
+3

Les surcharges sont sélectionnées en fonction du type * static * de l'argument et non du type dynamique. –

+2

Tout ce qui compte ici est l'interface de classe. Votre problème est que la classe de base fait référence à 'Entity' et qu'elle est dérivée de' Player' etc. Vous avez besoin de la classe de base pour avoir des méthodes 'virtual' pour chaque type dérivé, ou implémentez Double Dispatch d'une autre manière. – Keith

+0

collideWith de la classe de base (Entity *) a un mot-clé virtuel pour que ses classes dérivées puissent le redéfinir, comme Player :: collideWIth (Bullet *) – JBRPG

Répondre

2

Le problème est que vous êtes essayer de faire C++ faire multiple dispatch pour vous, ce qu'il ne fait pas, tout simplement.

Les méthodes ayant le même nom mais des types d'arguments différents sont, à toutes fins pratiques, des méthodes complètement différentes et ne se chevauchent donc pas mutuellement. Étant donné que votre variable q est probablement de type Entity *, l'appel de méthode résout statiquement comme un appel à Entity::collideWith(Entity *) et toutes les autres méthodes sont ignorées entièrement.

+1

fou est que la page wikipedia utilise à peu près ce cas précis dans son code d'exemple. –

+1

Oui, et il semble que la seule façon de le résoudre est d'utiliser l'exemple wiki comme modèle. Je vais essayer de voir si ça marche ou pas. et je veux en savoir plus sur cet effet d'appel statique – JBRPG

+0

Cela fonctionne! Merci et j'ai reçu l'aide d'une vraie personne aussi. – JBRPG