【问题标题】:Returning pointer to item cached in a std::map返回指向缓存在 std::map 中的项目的指针
【发布时间】:2013-04-19 11:26:42
【问题描述】:

我有一个充当缓存的类。它有以下私有成员:

std::map<std::string, Foo> _cache;

我需要为此缓存编写一个 getter,它返回一个引用、指针、迭代器或智能指针,指向存储在缓存中的 Foo 对象。如果需要,我希望客户端能够通过 getter 更新 Foo 对象。

但是,如果在缓存中找不到该项目,我不希望 getter 抛出。相反,客户端应该测试返回的值以确定是否找到了该项目。但是,如果您推荐这种方法,我可以说服我投掷。

你会为我的 getter 推荐什么返回类型?

我正在使用 boost 和 C++98。

【问题讨论】:

  • 如何从缓存中获取项目?项目是否总是由 std::string 标识?如果您希望客户端能够修改索引字符串(我假设它也是 Foo 的成员),那么您的地图索引完整性就有问题。如果 index 不是 Foo 的成员,则指针或引用是安全的。否则,我建议您重新考虑写入启用缓存,仅返回 const 引用。
  • std::string 用于查找。它不应该从外面改变。
  • 返回指针有什么问题吗?如果找不到对象,则可以为 NULL。
  • 你看过 boost::optional 吗?

标签: c++ boost c++98


【解决方案1】:

听起来您需要一个 boost::optional&lt;Foo&amp;&gt; 返回值 (optional references)。您的代码应如下所示:

class YourCache {
    std::map<std::string, Foo> _cache;
public:
    boost::optional<Foo&> FooByName(const std::string& name)
    {
        std::map<std::string, Foo>::iterator itr = _cache.find(name);
        if(_cache.end() == itr)
            return boost::none;
        return boost::optional<Foo&>(itr->second);
    }
};
  • getter 不会抛出 :)
  • 尊重 _cache 的现有实现(您不必更改它来存储智能指针 - 或一般的指针)
  • 在客户端代码中不能直接访问内存(就像返回 Foo* 一样)
  • 以最佳方式表达意图(“返回值是可选的/可能缺少”)
  • 在客户端代码中提供显式和自然的界面:

例如:

// client code:
if (boost::optional<Foo&> result = YourCache.FooByName("FOO")) {
    // only run if result is in cache
    result->bar();
}

【讨论】:

    【解决方案2】:

    在您的情况下,由于返回空指针的可能性,引用是没有问题的。迭代器也是不行的,因为您无法测试它是否实际上指向一个元素而无法访问缓存的 .end() 函数,该函数是私有成员。除非你提供一个接口来测试是,但这是一个矫枉过正。

    唯一的其他选择是返回一个指针。但是,这样你就必须保证指针在调用者使用它的整个过程中保持有效。一种方法是实现共享指针的映射,即:

    std::map<std::string, boost::shared_ptr<Foo> > _cache;
    

    这样,即使对象被抛出缓存,调用者仍然会得到一个有效的指针。并且shared_ptr可以进行布尔测试,所以如果在缓存中没有找到一个项目,你可以返回一个空的shared_ptr。

    但对缓存的上下文知之甚少,无法告诉您更多信息(例如,是否需要同步等)。

    【讨论】:

      【解决方案3】:

      使用持有 Foo 引用的 boost::optional 作为 getter 的返回值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-24
        • 2016-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多