从具有for循环的函数返回时检查对象是否存在

时间:2015-10-07 15:43:56

标签: c++ oop for-loop error-handling

我希望找到安全使用此类代码的正确方法:

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()函数中吗?我不确定因为返回值是Entity,所以必须返回一个Entity对象。 (同样,如果它是一个指针,这不是我项目中的代码,只是一个类似的例子)。

3 个答案:

答案 0 :(得分:0)

如果你可以改变返回类型:make getEntity()返回一个指针,如果对象不存在则返回NULL。

或者@ TartanLlama建议你可以返回一个迭代器。

其他选项(仅在某些情况下有效):您的方法可以记住上次调用它的entityName和结果索引。当你输入时,首先检查当前输入是否等于前一个输入:在这种情况下,你返回存储的索引而不再搜索。

答案 1 :(得分: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;
}

答案 2 :(得分: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);
}