簡體   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