使用unique_ptr并返回引用,或者我应该使用shared_ptr并在需要时制作副本
Use a unique_ptr and return a reference or should I use a shared_ptr and make copies if needed
我有一个缓存,它将对象的唯一 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
这将导致我不得不
- 将纹理传递给每个对象的构造函数,即使它们不需要纹理。 创建一个从游戏对象
- 继承的纹理游戏对象,并添加纹理成员和构造函数。
- 使用共享指针而不是唯一指针,并能够返回副本
现在我的问题是
在这种特定情况下,什么会被视为最佳实践? 我应该使用上述选项之一还是错过了更好的选项?
我知道我的问题不是最具体的,但我正在自己学习 c++,如果能得到别人对此的看法会很好。
假设ResourceCache
持有Texture
,这是我的想法。一般来说,似乎没有一个最好的解决方案。
- 将纹理传递给每个对象的构造函数,即使它们不需要纹理。
- 你需要传递一个虚拟对象,所以如果你想用这种方式,我建议把它保留为原始指针
- 通过这样做,您可以检查它是否真的有指针,因为它可以
nullptr
- 注意 无论是引用还是指针,都应确保
ResourceCache
的寿命超过所有GameObject
- 必须手动管理生存期
创建一个从游戏对象 - 继承的纹理游戏对象,并添加纹理成员和构造函数。
- 这可能是一种选择,但我认为这更像是一个设计问题
- 使用共享指针而不是唯一指针,并能够返回副本
- 这将正常工作
- 安全(没有双重删除/悬空指针等问题(
- 共享指针具有开销
相关文章:
- 用callgrind追踪不必要的副本
- CLANG 编译器 说:变量"PTR"可能未初始化
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 检查注册表项是否链接到(或副本)另一个注册表项
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为什么构建目录中新构建的共享库与安装目录中的副本具有不同的依赖项集?
- C++基于范围的 for 循环和元素副本
- 创建提升::shared_ptr的深层副本
- 为共享 ptr 向量实现复制 c'tor?
- 如何从构造函数副本 T(const T&)调用对象 T?
- 副本初始化的默认模板参数推导
- C++深浅的副本
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- Eigen - matrix.transpose 会创建矩阵的副本吗?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- gcc共享ptr副本分配实现