hax*_*por 5 c++ casting interface cocos2d-x
我已经定义了如下所示的接口类.
class IRecyclableObject
{
public:
virtual ~IRecyclableObject() {}
virtual void recycle() = 0;
virtual void dump() = 0;
virtual int getRecycleTypeID() = 0;
};
Run Code Online (Sandbox Code Playgroud)
以下是我的CharacterAI类,它继承了另一个类并实现了上面的接口类.它的定义如下.
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();
...
};
Run Code Online (Sandbox Code Playgroud)
接口中定义的那三个虚函数,我已经在CharacterAI类中实现了它.没有什么花哨的.
是时候将它们与ObjectPool(一个自制的)类一起使用,其中可用对象的数据存储在
m_freeList
Run Code Online (Sandbox Code Playgroud)
使用CCArray类.
以下代码中出现此问题.
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;
}
Run Code Online (Sandbox Code Playgroud)
预期的结果是显示
recycleTypeID : 4 4 4
Run Code Online (Sandbox Code Playgroud)
但是我得到了
recycleTypeID : 524241408 4 4
Run Code Online (Sandbox Code Playgroud)
第一个显然是垃圾,并且每个循环随机不同.我试图在返回之前在CharacterAI类中的实现函数getRecycleTypeID()中放置一个断点.我发现只有
obj1->getRecycleTypeID()
Run Code Online (Sandbox Code Playgroud)
被召唤但不是另一个.
通过关注obj变量,可以清楚地看到它看起来似乎是不同的对象调用,并且原因可能来自于将对象转换为接口类,并且如果从那里使用它是错误的或某种类型的话.
那里发生了什么?我可以将对象类型类转换为接口类指针(它实现)并正确调用接口类中定义的函数吗?
我可以将对象类转换为它实现的接口指针吗?
是.但那不是你的情况.函数objectAtIndex()返回一个指向CCObject,那类绝对不会不实现IRecyclableObject接口.
因此,残酷的C样式CCObject*转换IRecyclableObject*将导致重新解释前一类型的对象的布局,就好像它是后一种类型的对象一样.这很糟糕,并导致未定义的行为.
您应该使用dynamic_cast<>以将您CCobject*转换为IRecyclableObject*:
IRecyclableObject* obj = dynamic_cast<IRecyclableObject*>(
m_freeList->objectAtIndex(i)
);
Run Code Online (Sandbox Code Playgroud)
但请注意,如果您只想将指针最终强制转换为类型的对象,则甚至不需要这样做CharacterAI.只需将其直接转换为该类型:
CharacterAI* obj = dynamic_cast<CharacterAI*>(m_freeList->objectAtIndex(i));
Run Code Online (Sandbox Code Playgroud)
dynamic_cast<>如果您尝试强制转换的指针指向的对象的运行时类型不是(等于或派生自)目标类型的向下转换,则返回空指针.因此,在您不确定指向对象的具体类型的情况下,请不要忘记在解除引用之前检查返回的指针是否为非null.