0

我有两节课。超类是“组件”类,子类是“变换”类。

我正在使用的框架有一个函数,它返回特定类型的组件列表。但是,该列表会将它们作为组件返回,因为类型不限于特定的子类(但这是我使用它的方式)。

因此,在以下场景中,我知道所有返回的组件都将属于 Transform 子类。我正在做的是遍历列表,然后将每个组件转换为 Transform。这是我的代码:

std::list<Cistron::Component*,std::allocator<Cistron::Component*>> playerTransforms = objectManager->getComponents(player,"Transform");
std::list<Cistron::Component*>::iterator playerComponentIterator = playerTransforms.begin();
for (playerComponentIterator; playerComponentIterator != playerTransforms.end(); playerComponentIterator++)
{
    Transform *tmpTransform = static_cast<Transform*> (*playerComponentIterator);
    std::cout << tmpTransform->x ;
    std::cout << tmpTransform->y ;
}

这效率如何?我对 C++ 很陌生,所以我不知道是否有更好的方法来做到这一点。

4

2 回答 2

2

这不是一个好的设计,您的编译器应该在这种情况下生成警告。通常,您应该使用 dynamic_cast 向上转换您的指针。这种转换有一些运行时成本 - 与虚拟方法调用大致相同,但如果您尝试转换不兼容的指针,它将产生异常。尝试重新设计您的应用程序以消除此代码。你应该只调用Component类的虚拟方法,你不应该将指针转换Component为指向Transform. 这件事表明设计不好。

一种可能的设计是制作getComponents一个模板方法来消除强制转换:

template<class T>
list<T*> getComponents(Player* player, std::string name) {
    ...
}

或者也许只是这个:

list<Transform*> getTransfromComponents(Player* player) {...}

在您无法重构此代码的情况下,您始终可以转换您的列表:

    list<Component*> rlist = ...
    list<Transform*> llist;
    // Upcast all
    transform(rlist.begin(), 
              rlist.end(), 
              back_inserter(llist), 
              [](Component* r) {
                  return dynamic_cast<Transform*>(r);
    });
    // Remove all null values
    llist.remove(nullptr);
于 2013-11-03T12:54:22.840 回答
1

std::list通常实现为双链表,这意味着元素分散在内存中,这意味着迭代它很慢。检查:为什么在一个大的 std::list 上迭代这么慢?

但我更担心的是反射的使用:

objectManager->getComponents(player,"Transform");

这实际上可能是这段代码的真正瓶颈。

于 2013-11-03T12:59:16.873 回答