我有一个旅程矢量和一个位置矢量。旅行在两个地方之间。
struct Data {
std::vector<Journey> m_journeys;
std::vector<Locations> m_locations;
};
struct Journey {
?? m_startLocation;
?? m_endLocation;
};
如何创建每个旅程与两个地点之间的关系?
我以为我可以存储引用/指针到开始和结束位置,但是如果向量中添加了更多位置,那么它将重新分配存储并将所有位置移动到内存中的其他位置,然后指向位置的指针将指向垃圾。
我可以存储地名,然后搜索数据中的列表,但这需要保留对数据的引用(打破封装/ SRP),然后是一个效率不高的搜索。
我认为如果所有对象都是在堆上创建的,那么可以使用shared_ptr(因此Data将包含std::vector<std::shared_ptr<Journey>>
),那么这会有用吗? (这需要大量重写,所以避免这样做会更好)
是否有一些C ++ / STL功能类似于指针,但摘要/独立于内存位置(或向量中的顺序)?
答案 0 :(得分:2)
我想为你的位置索引制作一个vector<shared_ptr<Location>>
,而Journey将包含两个weak_ptr<Location>
。
struct Data {
std::vector<Journey> m_journeys;
std::vector<std::shared_ptr<Location>> m_locations;
};
struct Journey {
std::weak_ptr<Location> m_startLocation;
std::weak_ptr<Location> m_endLocation;
};
std::weak_ptr可以悬挂,这正是你想要的。 :)
关注的是,可以访问包含已删除位置的旅程。弱指针提供了一个expired()
方法,可以告诉您父共享指针(位于m_locations
向量中)的数据是否仍然存在。
从弱指针访问数据是安全的,并且需要使用lock()
方法。
以下是一个通常使用弱指针的一个很好的例子: http://en.cppreference.com/w/cpp/memory/weak_ptr/lock
答案 1 :(得分:2)
不,没有任何“C ++ / STL功能就像一个指针,但摘要/独立于内存位置”。
答案就是这样。
对于类之间的这种关系,这根本不是正确的容器集。您必须首先为对象选择适当的容器,而不是先选择一些任意容器,然后尝试弄清楚如何使它与您的关系一起工作。
使用std::shared_ptr
s的向量将是一个选项,只需要注意循环引用。另一种选择是使用std::list
而不是std::vector
,因为std::list
在增长时不会重新分配。
如果每个Locations
实例都有某种唯一标识符,请使用std::map
,然后使用该位置标识符引用某个位置,然后在地图中查找。虽然std::map
也不会在增长时重新分配,但间接层也提供了一些价值。