[英]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.