Reputation: 31597
I'm curious what constructs or language features, available in both the current C++ as well as in C++11, can be used to deduce the type of an object. An example:
class Base {
};
class DerivA
: public Base {
};
class DerivB
: public Base {
};
void foo(Base* obj) {
// Identify if `obj` is a `DerivA` or a `DerivB`
}
This is an oversimplification. It would appear that rather than having a way to identify the type, the best solution is to have overloads of the function for the two derived types and do away with the base class.
My real use case is one where one class is not interested in the exact type of the object (ie. just needs an implementation of Base
) and another class needs to know exactly what implementation of Base
the first class is using.
This happens in a component-based game entity system. The base would be an EntityState
and its derived types are StandingState
, DeadState
, etc. Class Entity
is the one that only needs a generic EntityState
object and class EntityRepresentation
needs to know exactly what state the entity is in to decide whether to draw the "standing" animation or the "dead" animation, or whatever.
Edit: Of course, if possible, I'd like to implement the game in such a way that not even the entity representation needs to know the type of the entity state. If there's a way to do that, then I'd use it. :) I'll look into the visitor pattern.
Upvotes: 4
Views: 263
Reputation: 208446
Contrary to most of the suggestions, I would not use RTTI directly (either typeinfo or dynamic_cast). There are different things that you can do:
The simplest solution is probably 1), just add a virtual method that will tell you in what state the object is, and use that to determine how to animate the object. The problem with this approach is that it requires adding methods to the State classes for each one of the things that will need it: animation, sound, movement calculations...
Using a form of double dispatch like the visitor pattern moves the complexity away from the State hierarchy into the visitors hierarchy, that must contain overloads for each different State (at all levels). The model in the application will be simpler, but usage of that model will become more cumbersome.
Upvotes: 1
Reputation: 288
Usually better alternative than trying to query the type of the object would be to add a virtual function to the base class:
class Base { public: virtual int Animation() const=0; };
class DerivA : public Base { public: int Animation() const { return 0; } };
class DerivB : public Base { public: int Animation() const { return 1; } };
And then have all the different animations identified by that one integer, maybe having a non-modifiable array of animations:
Animation anim1, anim2, anim3;
Animation *array[5] = { &anim1, &anim2, &anim3 };
void foo(Base *b) {
int animnum = b->Animation();
Animation *anim = array[animnum];
...
}
That's at least one way to make it work properly.
Upvotes: 0
Reputation: 361692
The problem you described in the last paragraph can be solved using visitor pattern. Have you tried it? It can solve the problem without even knowing the type its operating on.
Upvotes: 1
Reputation: 206616
Two ways:
If your classes are polymorphic use, dynamic_cast
or else you can use typeid
Usage of typeid
#include <typeinfo.h>
typeid(YourClass).name()
Usage of dynamic_cast
DerivA& dynamic_cast<DerivA&> (object);
DerivA* dynamic_cast<DerivA*> (object);
there must be least one virtual function in Base class to make dynamic_cast work or you will get compilation errors.
If you try to cast to pointer to a type that is not a type of actual object, the result of the cast will be NULL. For a similar situation in case of references the cast will throw a bad_cast
exception.
Upvotes: 3
Reputation: 7602
Assuming your types have a virtual method in them, you can use real time type identification (RTTI) of C++ with things like dynamic_cast and typeid
However, a better design might be to implement virtual methods to hide the types completely. For example:
class EntityState {
virtual void Draw( Entity entity ) = 0;
}
class DeadState : EntityState {
virtual void Draw( Entity entity ) {
//*** render the entity as dead
}
}
class AliveState : EntityState {
virtual void Draw( Entity entity ) {
//*** render the entity as alive!
}
}
class Entity {
EntityState myEntityState;
void Draw() {
myEntityState.Draw( this );
}
}
Your entities now can be drawn as either dead or alive without any if-then-else or switch statement code which would need updated if you suddently wanted new states to be added to your entity.
Upvotes: 0
Reputation: 11636
You can use dynamic_cast
for that:
if(DerivA * derivA = dynamic_cast<DerivA*>(obj)){
// it is a DerivA
}
Upvotes: 6
Reputation: 5973
for inheritence, I would look into static_cast and dynamic_cast. You can use these to determine if a an object is inherited from a class.
Upvotes: -1
Reputation: 73493
You can use dynamic_cast
to identify the type of the derived class object. For example, when you do: DerivedA* p = dynamic_cast<Derived*>(pBase);
if p!=NULL
condition is satisfied then its an object of DerivedA
type.
Upvotes: 1