I have defined an interface class like the following.
class IRecyclableObject
{
public:
virtual ~IRecyclableObject() {}
virtual void recycle() = 0;
virtual void dump() = 0;
virtual int getRecycleTypeID() = 0;
};
The following is my CharacterAI class which inherits another class and implements above interface class. It's defined as follows.
class CharacterAI : public harp::Character, public harp::IRecyclableObject
{
public:
CharacterAI();
virtual ~CharacterAI();
...
// -- note these 3 virtual functions -- //
virtual void recycle();
virtual void dump();
virtual int getRecycleTypeID();
...
};
Those three virtual functions as defined in interface, I have implemented it normally in CharacterAI class. Nothing fancy goes there.
It's time when I put them into use with ObjectPool (a self-made) class in which the data storage of available objects in
m_freeList
uses CCArray class.
The problem occurs in the following code.
IRecyclableObject* ObjectPool::popFreeObjectAndAddToActiveListForType(int recycleTypeID)
{
// search from free-list
for(unsigned int i=0; i<m_freeList->count(); i++)
{
IRecyclableObject* obj = (IRecyclableObject*)m_freeList->objectAtIndex(i);
CharacterAI *obj1 = (CharacterAI*)m_freeList->objectAtIndex(i);
CCLog("recycleTypeID : %d %d %d", obj->getRecycleTypeID(), recycleTypeID, obj1->getRecycleTypeID());
...
}
return NULL;
}
The expected result is to show
recycleTypeID : 4 4 4
But I got
recycleTypeID : 524241408 4 4
The first one is clearly garbage there and randomly different from each loop. I tried to put a breakpoint in the implemented function getRecycleTypeID() inside CharacterAI class before it returns. I found out that only
obj1->getRecycleTypeID()
was called but not another.
By focusing on obj variable, It's clearly seen that it seems different object calls that function, and the cause may come from casting an object to interface class and use if from there in which it's wrong or some kind.
What's going on there? Can I cast an object type class to interface class pointer (which it implements) and correctly call functions as defined in interface class?
Can I cast an object class to the interface pointer in which it implements?
Yes. But that's not your case. Function objectAtIndex()
returns a pointer to a CCObject
, and that class definitely does not implement the IRecyclableObject
interface.
Thus, a brutal C-style cast of CCObject*
to IRecyclableObject*
will result in reinterpreting the layout of an object of the former type as if it was an object of the latter type. That's bad, and leads to Undefined Behavior.
You should use dynamic_cast<>
to cast your CCobject*
to a IRecyclableObject*
:
IRecyclableObject* obj = dynamic_cast<IRecyclableObject*>(
m_freeList->objectAtIndex(i)
);
Notice, however, that this is not even needed if you just want your pointer to be eventually cast to an object of type CharacterAI
. Just directly cast it to that type:
CharacterAI* obj = dynamic_cast<CharacterAI*>(m_freeList->objectAtIndex(i));
dynamic_cast<>
returns a null pointer if the run-time type of the object pointed to by the pointer you are trying to cast is not (equal to or derived from) the target type of the downcast. Therefore, in those cases where you are not sure about the concrete type of the pointed object, don't forget to check whether the returned pointer is non-null before dereferencing it.
If 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