1

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

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

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

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

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

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

4

3 回答 3

4

听起来您需要一个boost::optional<Foo&>返回值(可选引用)。您的代码应如下所示:

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);
    }
};
  • 吸气剂不扔:)
  • 尊重 _cache 的现有实现(您不必更改它来存储智能指针 - 或一般的指针)
  • 不能直接访问客户端代码中的内存(如返回 Foo* 会)
  • 以最佳方式表达意图(“返回值是可选的/可能丢失”)
  • 在客户端代码中提供显式和自然的接口:

例如:

// client code:
if (boost::optional<Foo&> result = YourCache.FooByName("FOO")) {
    // only run if result is in cache
    result->bar();
}
于 2013-04-19T12:48:51.073 回答
2

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

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

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

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

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

于 2013-04-19T12:17:27.497 回答
1

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

于 2013-04-19T12:25:55.200 回答