4

So, I have a base class PhysicsObject, a sub-class Colliding, and two classes that derive from that again, Static and Newtonian.

When checking for collisions, I write all collisions to a std::vector< std::pair< Colliding*, Colliding*> > collisionVector. (The collision detection is fairly basic and it's not really part of the question.)

Now, after all collisions were detected, I iterate over the collisionVector and call the static collide method, which has these four overloads:

void collide(Newtonian* first, Newtonian* second);
void collide(Newtonian* object, Static* obstacle);
inline void collide(Static* obstacle, Newtonian* object){ collide(object, obstacle); }
void collide(Static* first, Static* second);

The problem is that I have to check what kind of objects I'm dealing with every single time, and it is possible that I introduce more subclasses of Colliding.

How do I decide which overload to call in an easy manner?


Current code:

This is how my code currently looks. Not pretty.

for (pair<Collision*,Collision*> coll : collisionVector){
    Colliding* first = get<0>(coll);
    Colliding* second = get<1>(coll);

    if (Newtonian* firstNewt = dynamic_cast<Newtonian*>(first)){
        if (Newtonian* secNewt = dynamic_cast<Newtonian*>(second)){
            collide(firstNewt, secNewt);
        }
        else if(Static* secStat = dynamic_cast<Static*>(second)){
            collide(firstNewt, secStat);
        }
    }
    else if(Static* firstStat = dynamic_cast<Static*>(first)){
        if (Newtonian* secNewt = dynamic_cast<Newtonian*>(second)){
            collide(firstStat, secNewt);
        }
        else if(Static* secStat = dynamic_cast<Static*>(second)){
            collide(firstStat, secStat);
        }
    }
}
Community
  • 1
  • 1
iFreilicht
  • 13,271
  • 9
  • 43
  • 74
  • My recommendation is always to avoid syntactic overloading altogether. – Daniel Daranas May 05 '14 at 09:24
  • But I have to handle the collision between `Static` and `Newtonian` Objects differently. If you see another way, please post it as an answer! I would be happy to avoid that sort of problem altogether. – iFreilicht May 05 '14 at 09:28
  • Syntactic overloading can _always_ be avoided. Just write the same functions but with different names, such as collideNewtonianNewtonian and collideNewtonianStatic. I am not posting an answer because you are asking how to decide which _overload_ to call, and I am just advicing you not to overload in the first place. This advice is sometimes controversial, but only for other people, not for me. I never, _ever_ use syntactic overloading. – Daniel Daranas May 05 '14 at 09:36
  • @DanielDaranas is there a specific reason why you wouldn't want to do that or is it just your personal preference? – iFreilicht May 05 '14 at 09:41
  • Code is more readable without syntactic overloading. One name for each thing, different names for different things. Not using it keeps the principle of least surprise. It is resolved at compile time anyway, not at run time, so by using it you gain no specific runtime advantage at the cost of compile time readability. – Daniel Daranas May 05 '14 at 09:48
  • For more theoretical arguments against syntactic overloading see Bertrand Meyer's book [Object-Oriented Software Construction, 2nd Edition](http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction), and his article [Overloading vs. Object Technology](http://se.inf.ethz.ch/~meyer/publications/publications/joop/overloading.pdf). – Daniel Daranas May 05 '14 at 09:50
  • possible duplicate of [C++ Double Dispatch for Equals()](http://stackoverflow.com/questions/7393458/c-double-dispatch-for-equals) – Yakk - Adam Nevraumont May 05 '14 at 11:22
  • @Yakk that question was about a failed double dispatch implementation, I asked for a way around the `dynamic_cast`s, and the *answer* was multiple dispatching. – iFreilicht May 05 '14 at 13:20
  • The design pattern for that problem is multiple dispatch. See [SO](http://stackoverflow.com/questions/1749534/multiple-dispatch-in-c) and a further [link](http://www.gamedev.net/topic/453624-double-dispatch-in-c/) in this answer. – frank May 05 '14 at 09:29

1 Answers1

1

I don't know if there's a simple C++ trick that can help you (what you need is virtual function resolution for two objects at once...).

If you only have to handle 2 concrete types (Newtonian and Static), I would keep the code you already have. If you want to support a lot more types, you'll need to make your code general, so that you don't write N^2 cases.

I would implement some sort of Colliding processing registration, where you register two concrete types and the method that handles them. It won't be easy, though.

zmbq
  • 38,013
  • 14
  • 101
  • 171