我已经定义了如下的接口(interface)类。

class IRecyclableObject
{
public:
    virtual ~IRecyclableObject() {}

    virtual void recycle() = 0;
    virtual void dump() = 0;
    virtual int getRecycleTypeID() = 0;
};

以下是我的CharacterAI类,该类继承了另一个类并实现了上面的接口(interface)类。它的定义如下。
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();

    ...
};

接口(interface)中定义的这三个虚函数,我通常在CharacterAI类中实现了它。没什么幻想的。

是时候将它们与ObjectPool(一个自制的)类一起使用了,在该类中,可用对象的数据存储在
m_freeList

使用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;
}

预期结果显示
recycleTypeID : 4 4 4

但是我得到了
recycleTypeID : 524241408 4 4

第一个显然是那里的垃圾,并且每个循环随机不同。
我尝试在CharacterAI类中的实现函数 getRecycleTypeID()中放置一个断点,然后再返回。我发现只有
obj1->getRecycleTypeID()

被称为而不是

通过关注obj变量,可以清楚地看到,似乎不同的对象调用了该函数,并且原因可能是由于将对象强制转换为接口(interface)类并在错误或某种类型的情况下使用而导致的。

那里发生了什么事?
我可以将对象类型类强制转换为接口(interface)类指针(由它实现)并按接口(interface)类中的定义正确调用函数吗?

最佳答案



是的。但这不是你的情况。函数objectAtIndex()返回一个指向CCObject的指针,并且该类肯定不实现IRecyclableObject接口(interface)。

因此,残酷的C风格的CCObject*IRecyclableObject*的转换将导致重新解释前一种类型的对象的布局,就好像它是后一种类型的对象一样。不好,并且导致 Undefined Behavior

您应该使用dynamic_cast<>CCobject*转换为IRecyclableObject*:

IRecyclableObject* obj = dynamic_cast<IRecyclableObject*>(
    m_freeList->objectAtIndex(i)
    );

但是请注意,如果只希望最终将指针强制转换为CharacterAI类型的对象,则甚至不需要这样做。只需将其直接转换为该类型即可:
CharacterAI* obj = dynamic_cast<CharacterAI*>(m_freeList->objectAtIndex(i));

如果您尝试转换的指针所指向的对象的运行时类型不是向下转换的目标类型(等于或派生),则dynamic_cast<>返回空指针。因此,在不确定所指向对象的具体类型的情况下,请不要忘记在取消引用之前检查返回的指针是否为非空。

关于c++ - 我可以将对象类强制转换为实现它的接口(interface)指针吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14923538/

10-11 22:51
查看更多