I'm building a simple game design for a project of mine. I have the following classes:
class Character
{
public:
virtual void Display();
virtual void SetParameters( char* param, ... );
};
class NonPlayableCharacter : public Character
{
public:
virtual void Display();
virtual void SetParameters( char* paaram, ... );
int GetNPCState();
}
And then I have a bunch of classes that derive either from Character or NonPlayableCharacter. I define it like so:
std::vector<Character*> _allChar;
My problem is that at any given time I would want to perform some operation on one of the element of the vector. So getting an element out of the vector I can't directly call the method GetNPCState()
because the element in the vector are of Character* type. So doing this:
_allChar[0]->GetNPCState();
doesn't work. So I tried doing it with the famous dynamic_cast:
NonPlayableCharacter* test = dynamic_cast<NonPlayableCharacter*>(_allChar[0]);
test->GetNPCState();
The problem with this last attempt is that GetNPCState()
crashes because the object is null, and I know for a fact (via debugging) that _allChar[0] isn't null.
Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.
You can cast a pointer to another pointer of the same IBM® i pointer type. Note: If the ILE C compiler detects a type mismatch in an expression, a compile time error occurs. An open (void) pointer can hold a pointer of any type.
Downcasting is not allowed without an explicit type cast. The reason for this restriction is that the is-a relationship is not, in most of the cases, symmetric. A derived class could add new data members, and the class member functions that used these data members wouldn't apply to the base class.
The Downcasting is an opposite process to the upcasting, which converts the base class's pointer or reference to the derived class's pointer or reference. It manually cast the base class's object to the derived class's object, so we must specify the explicit typecast.
There are several types of casts in C++ (4), of which 2 are of interests here:
static_cast
assumes that you know what you are doingdynamic_cast
checks, at runtime, that you "guessed" rightNote: simplified, as dynamic_cast
also allows cross-casts and casts involving virtual bases.
There are 3 versions of dynamic_cast
, really, depending on the nature of the target:
dynamic_cast<T&>(u)
), then if the check fails dynamic_cast
throws a std::bad_cast
exceptiondynamic_cast<T*>(p)
), then if the checks fails dynamic_cast
returns a null pointervoid*
, then dynamic_cast
instead returns the address of the full objectIn this case, you may:
dynamic_cast<NonPlayableCharacter*>(_allChar[0])->getNPCState()
to
dynamic_cast<NonPlayableCharacter&>(*_allChar[0]).getNPCState()
, and let the exception propagatesNonPlayableCharacter* test
here) for non-nullityIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With