c++ - 使用 unique_ptr 并返回引用,或者我应该使用 shared_ptr 并在需要时制作副本
问题描述
我有一个缓存,它将对象的唯一 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
这将导致我不得不
- 将纹理传递给每个对象的构造函数,即使它们不需要纹理。
- 创建一个继承自 GameObject 并添加 Texture 成员和构造函数的 TexturedGameObject。
- 使用共享指针而不是唯一指针并且能够返回一个副本
现在我的问题是
在这种特定情况下,什么被视为最佳实践?我应该使用上述选项之一还是错过了更好的选择?
我知道我的问题不是最具体的,但我正在自己学习 c++,如果能得到别人对此的看法会很好。
解决方案
假设ResourceCache
成立Texture
,这是我的想法。一般来说,似乎没有一种最佳解决方案。
- 将纹理传递给每个对象的构造函数,即使它们不需要纹理。
- 您需要传递一个虚拟对象,因此如果您想采用这种方式,我建议您将其保留为原始指针
- 通过这样做,您可以检查它是否真的有一个指针,因为它可以是
nullptr
- 注意无论是引用还是指针,您都应该确保它的寿命
ResourceCache
超过所有GameObject
- 必须手动管理生命周期
- 创建一个继承自 GameObject 并添加 Texture 成员和构造函数的 TexturedGameObject。
- 这可能是一个选择,但我认为这更像是一个设计问题
- 使用共享指针而不是唯一指针并且能够返回一个副本
- 这会很好用
- 安全(没有双重删除/悬空指针等问题)
- 共享指针有开销
推荐阅读
- javascript - Javascript / JSON如何访问数组的值
- r - 时间序列不绘制绘图类型
- python - 在虚拟环境(conda 或 venv)中以编程方式运行 Python 程序
- c++ - 我的析构函数是否给了我这个错误:*** `./main' 中的错误:双重释放或损坏(fasttop):?
- android - Android - GoogleApiClient - 不连接片段的负载
- python - 熊猫中是否有等效的excel公式
- python - 组织循环的最佳方式是什么?
- r - 交错来自 Rcpp 中的许多对象的结果
- python - Python 3,正确调用函数
- axios - 如何传递“|” Axios URL 中的符号?