Home > database >  How can I make a function use the child object associated function instead of the parent one?
How can I make a function use the child object associated function instead of the parent one?

Time:11-20

I'm coding a simple physics engine with a few others for a school assignment. In order to be as generic, we made a Particle class, then an Object class which inherits it (and is basically a particle with a force vector), and finally a Disc class which is a child class of Object. In my class PyhsicsWorld, I want to use a list of Objects and iterate on it to resolve collisions. For that, I declared the intersects(Object o1, Object o2) and GetPenDist(Object o1, Object o2) functions, but they aren't supposed to be called. Instead, I'm overloading these functions in Disc and I want the program to use these instead. I only create and use Discs (for now), so I'm sure there isn't any reason (other than me not understanding my code) for the program to call intersects on Objects instead of Disc. Here is my code :

Object.h :

#include <iostream>

#include "./Particle.h"

class Object : public Particle {
//Some code
};

bool intersects(Object o1, Object o2);
float getPenDist(Object o1, Object o2);

Object.cpp :

#include "./Object.h"

bool intersects(Object o1, Object o2) {
    std::cout << "Bad Intersects" << std::endl;
    return false;
}

float getPenDist(Object o1, Object o2) {
    std::cout << "Bad PenDist" << std::endl;
    return 0;
}

Disc.h :


#include "./Object.h"

class Disc : public Object {

protected : 

    float radius;

public :
    float getRadius() { return radius; }

//Some code
};

bool intersects(Disc d1, Disc d2);
float getPenDist(Disc d1, Disc d2);

Disc.cpp :

#include "./Disc.h"

bool intersects(Disc d1, Disc d2) {
    return (d2.getPosition() - d1.getPosition()).getNorm() < d1.getRadius()   d2.getRadius();
}

float getPenDist(Disc d1, Disc d2) {
    return -(d2.getPosition() - d1.getPosition()).getNorm() - d1.getRadius() - d2.getRadius();
}

PhysicsWorld.h :

class PhysicsWorld {

protected:
    std::vector<Object*> objectList;

    void resolveCollisions(float duration);

};

PhysicsWorld.cpp :

#include "PhysicsWorld.h"

void PhysicsWorld::resolveCollisions(float duration) {

    std::vector<Object*>::iterator iter, iter2;

    for (iter = objectList.begin(); iter != objectList.end();   iter) {

        for (iter2 = objectList.begin(); iter2 != objectList.end();   iter2) {

            if (!(*iter == *iter2))
            {
                if (intersects(**iter, **iter2))
                {
                    //Do something
                }
            }
        }
    }
}

My problem here is that the code is running the Intersects(Object*, Object*) function in the resolveCollisions method while I'd like it to run the Intersects(Disc*, Disc*) function.

Please note that these classes are heavily simplified to only include relevant code. Furthermore, while I'd love to make Object::Intersects(Object o), I can't do that as I can't override it afterward with Disc::Intersects(Disc d).

Thank you very much for any help you can provide !

CodePudding user response:

If you really need to call for Disc, just cast it. I further assume that you need general solution for multiple shapes, like Disc, Cube, Sphere etc.

So I prepared example for you, that is based on virtual functions and shows how can you choose correct function for Disc and Cube.

class Disc;
class Cube;

bool intersectDiscVsDisc(Disc*, Disc*);
bool intersectCubeVsDisc(Cube*, Disc*);
bool intersectCubeVsCube(Cube*, Cube*);

class Object {
    public:
    virtual bool intersects(Object *) = 0;
    virtual bool intersectsVsDisk(Disc *) = 0;
    virtual bool intersectsVsCube(Cube *) = 0;
};

class Disc : public Object {
    virtual bool intersects(Object * another) override 
        { return another->intersectsVsDisk(this); }
    virtual bool intersectsVsDisk(Disc * another) 
        { return intersectDiscVsDisc(this, another); }
    virtual bool intersectsVsCube(Cube * another)
        { return intersectCubeVsDisc(another, this); }

};

class Cube : public Object {
    virtual bool intersects(Object * another) override 
        { return another->intersectsVsCube(this); }
    virtual bool intersectsVsDisk(Disc *another)
        {return intersectCubeVsDisc(this, another); }
    virtual bool intersectsVsCube(Cube *another)
        { return intersectCubeVsCube(this, another); }

};
  • Related