8

在游戏中,我想搜索项目地图并返回位于棋盘特定方格上的项目。但是如果广场是空的呢?(这些项目不存储在板结构中。就这个问题而言,不要介意。)我有下面的代码,但我应该怎么做才能返回“空”引用?

map<pair<int, int>, Item*> _items;

Item& itemAt(int row, int col) const {
    try {  
        return *_items.at(make_pair(row, col));
    } catch(out_of_range& e) {
        return // what goes here?            
    } 
}

或者这是错误的方法,我应该使用find()

4

4 回答 4

12

如果在您的程序中找不到项目不是错误条件,那么您不应该返回引用(因为引用不能为空)。相反,您应该返回一个(非拥有的,最有可能的)指针,并nullptr在未找到该项目的情况下返回:

Item* itemAt(int row, int col) const {
    try {  
        return _items.at(make_pair(row, col));
    } catch(out_of_range& e) {
        return nullptr;
    }   
}

另一方面,如果未找到项目是错误,那么您可以返回一个引用(当找到项目时)并在未找到项目时让异常传播- 处理它的责任将属于您的代码具有有关如何处理它的战略知识:

Item& itemAt(int row, int col) const {
    return *_items.at(make_pair(row, col));
}
于 2013-05-27T13:08:28.923 回答
9

在这种情况下,使用指针作为表示“零或一个对象”的方法很有用:

Item* itemAt(int row, int col) const {
    try {
        return _items.at(make_pair(row, col));
    } catch(out_of_range& e) {
        return nullptr;
    }
}

但是,使用std::map::find()可能是一种更快、更清洁的方法。

于 2013-05-27T13:09:03.660 回答
3

如果客户端代码请求不存在的项目是错误的,则throw报告失败并返回一个异常Item&

如果不是错误,则由于 的value_type已经mapItem*更改返回类型为 aNode*并返回nullptr以指示在所请求位置的项目不存在并使用map::find()

Item&为避免返回类型已经存在的生命周期问题,请考虑将 更改value_typestd::shared_ptr<Item>. 如果客户端代码有一个指向值的引用或原始指针,map并且该元素从 中删除,map则客户端留下一个悬空指针/引用。切换到 astd::shared_ptr<Item>可以避免这种情况。该itemAt()函数将返回一个std::shared_ptr<Item>. 这还有一个好处是Items 中的 smap不需要显式地deleted。

于 2013-05-27T13:09:11.663 回答
1

其实其他人也有同样的问题:

  • 他们中的一些人写道boost::optional
  • 你可以返回一对指针和返回值
  • 你可以抛出异常
  • 你可以返回一个空对象
于 2013-05-27T20:26:09.963 回答