繁体   English   中英

C ++遍历某个子类的列表

[英]C++ Iterating over a list of a certain subclass

我有两节课。 超类是“ Component”类,而子类是“ Transform”类。

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

因此,在以下情况下,我知道所有返回的组件都是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 ++还是很陌生,所以我不知道是否有更好的方法可以做到这一点。

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

一种可能的设计是使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");

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM