C++ How to tell if object is of a specific type

Started by
4 comments, last by AcidZombie24 15 years, 5 months ago
Hi all, I've been struggling with this, if only because I don't know the correct terminology. In my game I have a grapple gun which shoots rope and attaches itself to objects. Currently, it will attach to ANY object, but I'm trying to get it to only attach to objects which are derived from CGrappleObject. Here's an example:

class CGrapplePoint
{
   public:
      bool IsGrappled;
};

class CHealthPack : public CGeometry, CPickup, CGrapplePoint
{
   public:
      //Health pack related stuffs
};

Before shooting out a rope and attaching, I raycast ahead and see what to attach to. The raycast funstion returns a CGeometry* pointer, and I want to test to see if this object is also a CGrapplePoint object. I've tried the following:

if(dynamic_cast<CGrapplePoint*>(Raycastdata.Geometry)) ...
This always returns 0. And:

if(static_cast<CGrapplePoint*>(Raycastdata.Geometry)) ...
This gives me the compiler error:

error C2440: 'static_cast' : cannot convert from 'sym::CGeometry *' to 'CGrapplePoint *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Which is pretty obvious, because CGrapplePoint has no relation to CGeometry. What I DON'T want to do is have CGrapplePoint derive from CGeometry, which is probably what's making things complicated for me. I'm out of ideas for what to Google for. Any help appreciated.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

Advertisement
Searching for RTTI (run-time type information) should get you some details of how the dynamic_cast mechanism works. In this case your problem is probably that the base classes need to have a virtual function for dynamic_cast to function properly.
Quote:Original post by deadstar
I've been struggling with this, if only because I don't know the correct terminology.


What you're trying to do is a "cross cast" (search the page for "cross cast"), however I am unsure why it isn't working for you.

Are you sure the object you're returning is derived from both CGeometry and CGrapplePoint?
Quote:Original post by fpsgamer
Quote:Original post by deadstar
I've been struggling with this, if only because I don't know the correct terminology.


What you're trying to do is a "cross cast" (search the page for "cross cast"), however I am unsure why it isn't working for you.

Are you sure the object you're returning is derived from both CGeometry and CGrapplePoint?


I think this is what I'm trying to do, yes.

In the above example, Raycastdata.Geometry is ALWAYS derived from CGeometry, and may sometimes derive also from CGrapplePoint too.

I'm testing with both kinds of expected objects, but the dynamic_cast always returns 0.

Does it matter that Raycastdata.Geometry will have been casted to CGeometry* beforehand? It's obtained using (CGeometry*)NewtonBodyGetUserData(Body) inside the Raycast function.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

CGrapplePoint has no virtual functions. As Nitrage suggests make sure your base classes have a virtual function in them so that the rtti mechanism (vtables) are activated to build the runtime type info that permits the cross casts. gcc is at least nice enough to give a compile-time error stating that the dynamic_cast is impossible without at least one virtual such as destructor.

#include <iostream>struct A{     // required  for a->b cast     virtual void dummy() { } ; };struct B   {    // required for b->a cast    virtual void dummy() { } ; };struct D : public A, public B{}; int main(){    A *p = new D;      // cross-cast a to b    B *b = dynamic_cast< B *>( p);     std::cout << "b is " << b << std::endl;    // cross-cast b back to a    A *a = dynamic_cast< A *>( b);     std::cout << "a is " << a << std::endl;}

try doing ,public CGrapplePoint or change the class to struct and see if it compiles.

Also, why are you inheriting? why not do

class CGrapplePoint{   public:      bool IsGrappled;};class CHealthPack{   public:      //Health pack related stuffs   CGeometry geometry;   CPickup pickup;   CGrapplePoint grapplePoint;//i only made those public bc you made it public in your inheritance//you also have the ability to do something likeoperator CGrapplePoint& () { return grapplePoint; }};

<SkilletAudio> Your framerate proves your lack of manhood

This topic is closed to new replies.

Advertisement