Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Polymorphism

Status
Not open for further replies.

GameProgrammerDude

Programmer
Jan 26, 2004
2
US
Does anyone know a way I could implement the following functionality?

class CollidePrim
{
// blah
}

class Sphere : public CollidePrim
{
// blah
}

class Triangle : public CollidePrim
{
// blah
}

class PhysicsObject
{
CollidePrim *m_pCollidePrim;

void SetPrimitive();

void Update();
void Collide( Sphere& sS );
void Collide( Triangle& tT );
}

void PhysicsObject::SetPrimitive()
{
if( externaldata(Prim) == "Sphere" )
m_pCollidePrim = new Sphere;
else
m_pCollidePrim = new Triangle;
}

PhysicsObject::Update()
{
Collide( *m_pCollidePrim );
}

This code will not compile, but I think it is clear what I am trying to do. I want the compiler to choose which collide function depending on the collision primitive that is embedded in class PhysicsObject. And I would like to avoid using an abstract base class, because I don't want the overhead of a vtable. Anyway, I hope this is clear enough of an explanation.

Thanks.
 
If you want the complier to get the call to [tt]Collide[/tt] right, then you'll have to use a [tt]virtual[/i] function:
Code:
class CollidePrim {
    virtual void Collide() = 0;
};

class Sphere : public CollidePrim {
    virtual void Collide() { ... };
}

class Triangle : public CollidePrim {
    virtual void Collide() { ... };
}

class PhysicsObject {
    CollidePrim *m_pCollidePrim;

    void SetPrimitive();

    void Update() { m_pCollidePrim->Collide(); };
}
The compiler only "knows" that [tt]m_pCollidePrim[/tt] is a pointer to a [tt]CollidePrim[/tt]. It is at run-time that your [tt]SetPrimitive()[/tt] method sets its value (the compiler can't guess this).

If you really want to avoid [tt]virtual[/tt] functions (the [tt]vtable[/tt] overhead isn't that massive), then try:
Code:
class PhysicsObject {
    CollidePrim *m_pCollidePrim;
    enum PrimType {
          PT_Sphere
       ,  PT_Triangle
    };
    PrimType m_type;

    void SetPrimitive();

    void Update();
    void Collide( Sphere& sS );
    void Collide( Triangle& tT );
}

void PhysicsObject::SetPrimitive() {
    if (externaldata(Prim) == "Sphere") {
        m_pCollidePrim = new Sphere;
        m_type = PT_Sphere;
    } else {
        m_pCollidePrim = new Triangle;
        m_type = PT_Triangle;
    }
    return;
}

void PhysicsObject::Update() {
    switch (m_type) {
       case PT_Sphere:
          Collide((Sphere&) *m_pCollidePrim);
          break;
       case PT_Triangle:
          Collide((Triangle&) *m_pCollidePrim);
          break;
       default:
          break;
    }
    return;
}
However, I suspect that the overhead of all this will be greater than a [tt]vtable[/tt]. This example illuestrates why [tt]virtual[/tt] members exist.



[tt]________________________________________________________________
[pc2]Roger
Life is a game of cards in which the deck contains only jokers.[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top