简体   繁体   中英

Derived classes' functions not being called

I am dealing with the base class Entity, and I want its derived classes (Player, Enemy, Bullet) to have collideWith() called

I have attempted to get the derived functions of Entity's collideWith() to work, however, the base version is always called, which happens to be empty, even when I removed the keyword virtual

Base class Entity

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

and its function, which is always called during collision check

void Entity::collideWith(Entity*){ 

} 

Derived classes with collideWith function, without virtual keyword These never get called during collision check

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

Function for checking collisions p and q points to Entity* from EntityList, which contains its derived classes Player, Enemy, and 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);

                    }


                }
            }
        }
    }

}

The problem is that that you're trying to make C++ do multiple dispatch for you, which it doesn't do, quite simply.

Methods with the same name but different argument types are, for all intents and purposes, completely different methods, and as such do not override each other. Since your q variable is likely of type Entity * , the method call will resolve statically as a call to Entity::collideWith(Entity *) , and all the other methods are ignored entirely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM