我有一个结构如下:
struct T_MY_TOY {
uint32_t id;
float data;
};
我想定义一个自定义地图。 我的第一个实现是:
typedef std::map<uint32_t, T_MY_TOY*> T_MY_TOY_MAP;
使用智能指针或引用包装而不是T_MY_TOY*
是否正确?
typedef std::map<uint32_t, std::shared_ptr<T_MY_TOY> > T_MY_TOY_MAP;
或:
typedef std::map<uint32_t, std::reference_wrapper<T_MY_TOY> > T_MY_TOY_MAP;
哪种解决方案最好?
答案 0 :(得分:4)
几乎总是,最好的选择是存储对象。
如果有充分的理由,只存储指针或引用:要么是因为对象不是容器所有,要么是因为它们是多种多态类型。
在第一种情况下,容器不拥有对象。如果您可以保证在仍然在容器中时不会销毁对象,那么它可以存储原始指针。否则,通过存储shared_ptr
或weak_ptr
,您将需要安全的共享所有权语义。
在第二种情况下,容器拥有对象。单一所有权语义最好由unique_ptr
管理;如果您需要共享所有权,则可能需要shared_ptr
。
当您需要一个类似于对象而不是指针的类型(即不需要显式解除引用)时,使用引用包装器;它们通常用于期望对象类型的模板。当你控制你与元素的互动时,没有必要这样做;使用它们而不是原始指针只会通过隐藏间接引起轻微的混淆。由于它们不管理对象的生命周期,因此它们只能用于可以使用原始指针的情况。
答案 1 :(得分:2)
您的解决方案都不是最好的,最好的解决方案是按值存储:
typedef std::map<uint32_t, T_MY_TOY> T_MY_TOY_MAP;