2015-10-07 100 views
0

我期待找到使用這種代碼安全地以正確的方式返回時,存在對象:希望在何處檢查是否從函數與循環

renderer->renderEntity(entityManager->getEntity("player")); 

Entity EntityManager::getEntity(string entityName) 
{ 
    for (int index = 0; index < entityVector.size(); ++index) 
    { 
     if (entityVector[index].getName() == entityName) 
     { 
      return entityVector[index]; 
     } 
    } 
} 

從容器中得到內的對象一個類的實例,並且想要檢查它是否存在,所以你沒有對不存在的對象進行調用。

我知道我可以改變的呼籲:

if (entityManager->getEntity("player" != nullptr) 
{ 
    renderer->renderEntity("player"); 
} 

我想避免雙重調用來檢查對象存在。我想這可能是一個比語法問題更多的設計。我可以在包含for循環的getEntity()函數中構建錯誤檢查嗎?我不確定,因爲返回值是實體,所以必須返回一個實體對象。 (如果它是一個指針,則相同,這不是我的項目中的代碼,只是一個類似的例子)。

+1

常見的是如何認爲的那個實體名稱將不存在?如果這種情況很少發生,你可以拋出異常。另一種選擇是採用標準庫方法,並將一個迭代器返回給元素,如果它不存在,則返回'entityVector.end()'。 – TartanLlama

+0

如果實體不存在,您的方法應該返回什麼? –

+1

我會建議使用'std :: map' – Paranaix

回答

0

這應該有所幫助。一個簡單的空對象模式

https://en.wikipedia.org/wiki/Null_Object_pattern

class Entity 
{ 
public: 
    virtual void render() 
    { 
     // do somthing 
    } 
}; 

class EmptyEntity final : public Entity 
{ 
public: 
    void render() override 
    { 
     //Do nothing or print log 
    } 
} static g_EmptyEntity; 

Entity EntityManager::getEntity(string entityName) 
{ 
    for (int index = 0; index < entityVector.size(); ++index) 
    { 
     if (entityVector[index].getName() == entityName) 
     { 
      return entityVector[index]; 
     } 
    } 
    return g_EmptyEntity; 
} 
+0

這幾乎正是我想要的,覆蓋任何功能都沒有發生在我身上。真的很好的解決方案,我認爲會有一個設計模式!謝謝。 – martingrant

+0

當你按價值回報時,你得到了對象切片。 – Jarod42

+0

是Jarod42。但由於提問者沒有更多的細節,所以我不能包含所有的細節。實體和EntityManager :: getEntity(string entityName)可以幫助 –

0

如果您可以更改返回類型:make getEntity()返回一個指針,如果該對象不存在,則返回NULL。

或者,如@ TartanLlama建議您可以返回一個迭代器。

其他選項(只在某些情況下才有效):您的方法可以記住上次調用該方法的entityName以及生成的索引。輸入時首先檢查當前輸入是否等於先前的輸入:在這種情況下,您將返回存儲的索引而不再搜索。

+0

這會工作,但我希望能夠在使用它之前不必檢查對象是否爲NULL,所以我沒有太多的if語句堵塞代碼。 你的第二點是好的。我喜歡這一點,如果你正在尋找一個你最近發現的物體,就跳過搜索。絕對是我可以用來提高效率的東西,謝謝! – martingrant

+0

檢查對象是否爲NULL與檢查元素是否存在相同,它們是相同的情況。我不明白它如何幫助,除非這個方法findEntityByName()生成元素,如果它不存在。 –

0

返回指針將是簡單/更清晰:

Entity* EntityManager::findEntityByName(const std::string& entityName) 
{ 
    const auto it = std::find_if(entityVector.begin(), entityVector.end(), 
           [&](const auto& e) { 
             return e.getName() == entityName; 
           }); 
    if (it == entityVector.end()) { // Not found. 
     return nullptr; 
    } 
    return std::addressof(*it); 
} 

然後

auto* entity = entityManager->findEntityByName("player"); 
if (entity != nullptr) 
{ 
    renderer->renderEntity(entity); 
} 
+0

我希望得到的是在我使用它之前不需要檢查對象是否爲空的情況。但是在你的回答中有一些非常好的東西,我不知道std :: find_if()和std :: addressof()。謝謝,他們將在未來對我有用! – martingrant