使用unique_ptr并返回引用,或者如果需要,我应该使用shared_ptr并进行复制

问题描述 投票:1回答:1

我有一个缓存,它在无序映射中存储对象的唯一ptrs,并为缓存的用户返回对象的引用。它会按预期方式工作,将对象存储到超出范围为止。

缓存的实现如下:

将对象存储在缓存中:

template<typename T>
template<typename... Args>
void ResourceCache<T>::add(const std::string& name, Args... args)
{
    m_cache->try_emplace(name, std::make_unique<T>(args...));
}

从缓存中获取对象:

template<typename T>
T& ResourceCache<T>::getCachedElement(const std::string& name) const
{
    auto it = m_cache->find(name);

    if(it != m_cache->end())
        return *it->second;

    throw "resource not found";
}

但是现在我进入一个问题,即引用并不总是我想从缓存中获取的,例如:

我有以下对象:

class GameObject
{
public:
    void translate(const cheetah::Vector3f& position);
protected:
    Quaternion m_rotation;
    Vector3f m_position;
};

让我说该对象具有纹理,目前对我来说唯一的方法是添加一个成员引用

Texture& m_texture

[这将导致我不得不要么

  1. 将纹理传递给每个对象的构造方法,即使它们不需要纹理。
  2. 创建从GameObject继承并添加Texture成员和构造函数的TexturedGameObject。
  3. 使用共享指针而不是唯一指针并能够返回副本

现在我的问题是

在这种特定情况下,什么是最佳做法?我应该使用上述选项之一还是错过了更好的选择?

我知道我的问题不是最具体的,但是我正在自己学习c ++,很高兴得到其他人对此的看法。

c++ pointers
1个回答
0
投票

假设ResourceCache保持Texture,这是我的想法。一般而言,似乎没有最好的解决方案。

  1. 即使每个对象不需要纹理,也将纹理传递给构造函数。
    • 您将需要传递一个虚拟对象,因此,如果要使用这种方式,我建议您将其保留为原始指针
    • 通过执行此操作,您可以检查它是否确实具有指针,因为它可以是nullptr
    • 注意,无论是引用还是指针,您都应确保ResourceCache的寿命超过所有GameObject-寿命必须手动管理
  2. 创建一个继承自GameObject的TexturedGameObject,并添加一个Texture成员和构造函数。
    • 这可能是一个选择,但我认为这更多是设计问题
  3. 使用共享的指针而不是唯一的指针,并能够返回副本
    • 这会很好
    • 安全(没有类似双重删除/悬空指针的问题)
    • 共享指针有开销
© www.soinside.com 2019 - 2024. All rights reserved.