C++ 迭代某个子类的列表

C++ Iterating over a list of a certain subclass

本文关键字:列表 子类 迭代 C++      更新时间:2023-10-16

我有两个类。超类是"组件"类,子类是"转换"类。

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

因此,在以下场景中,我知道所有返回的组件都将属于 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++很陌生,所以我不知道是否有更好的方法。

这不是一个好的设计,在这种情况下,编译器应该生成警告。通常,您应该使用 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);

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

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

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

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