返回指向缓存在std::map中的项的指针

Returning pointer to item cached in a std::map

本文关键字:map 指针 std 缓存 存在 返回      更新时间:2023-10-16

我有一个类作为缓存。它有以下私有成员:

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

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

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

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

听起来您需要一个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);
    }
};
  • getter不抛出:)
  • 尊重_cache已经存在的实现(你不需要改变它来存储智能指针-或者一般的指针)
  • 不允许在客户端代码中直接访问内存(如返回Foo*将)
  • 以最好的方式表达了意图("返回值是可选的/可能会丢失")
  • 在客户端代码中提供了一个明确而自然的接口:
例如:

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

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

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

std::map<std::string, boost::shared_ptr<Foo> > _cache;
这样,即使对象从缓存中抛出,调用者仍然会留下一个有效的指针。shared_ptr可以进行bool测试,因此如果在缓存中没有找到项,则可以返回空shared_ptr。

但是我们对缓存上下文的了解太少,无法告诉你更多(例如,如果需要同步,等等)。

使用boost::optional来保存Foo引用作为getter的返回值