[英]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
的指针Transform
为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");
这实际上可能是这段代码的真正瓶颈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.