使用唯一成员ID标识对象是一个好主意吗?

4
我的问题是,如何让对象彼此关联。我有两个向量:vector babies和vector toys。每个婴儿和每个玩具都有一个唯一的成员int id。因此所有的婴儿和玩具都从0到n编号。
现在,每个Baby都有一个首选的Toy,每个Toy都有一个首选的Baby。到目前为止,我使用指针:Baby有一个指向他首选Toy的指针,而这个Toy有一个指向Baby的指针。(这没问题,因为我永远不会改变向量)然而,区分婴儿和玩具的是它们的ID,而不是它们在向量中的位置。
随着我的深入思考,我质疑了我的设计,并发现指针是可行的,但未来可能会导致问题。相反,如果我使用ID,我就可以做得很好,但我需要访问整个babies或toys向量。
在这种情况下,是否有常见的做法?使用指针是一个好主意吗?我应该编写自己的容器以智能地使用ID吗?
编辑: 我想补充一下,我已经考虑过使用map来关联baby和toy。然而,我在运行时确定baby和toy之间的关系(以及另一种方式)。查找这个关系是程序的一个重要部分。因此,我不确定是否可以使用map。但是,我会去看一下它(到目前为止还没有使用过)。此外,首选玩具和婴儿的信息必须成为对象的一部分,而不是(只是)超级数据结构的一部分。

如果你还没有听说过“字符串类型接口”,我鼓励你去了解一下。不要为每个ID使用int,而是使BabyIdToyId成为不同的类型;你不想意外地回收一个婴儿,对吧? - Matthieu M.
指针没问题。尽量不要使用ID - 或者只作为一个简单的属性,比如名称等... 指针始终是唯一的,而ID可能会被错误地复制。 - PiotrNycz
如果您担心存在泄漏指针的问题,则考虑使用智能指针(弱指针和共享指针)。 - PiotrNycz
是的,要使用向量索引,您需要引用向量。如果您想简化此过程,可以将向量引用和索引包装到一个对象中。现在,您基本上拥有了一个带有偏移量的指针,这对于诸如序列化或内存映射之类的事情非常有用。 - Zan Lynx
@Zan Lynx,你能延长一下吗? - dani
显示剩余3条评论
4个回答

2
使用唯一的 ID 作为关系的标识具有一些优点。这些 ID 不会像指针一样悬空,也不会像向量索引一样越界。它们可以轻松地序列化。当向量被重新分配或重新排序时,它们不会失效。
但是它们也有一些缺点。你需要确保它们始终保持唯一(使用 GUID 可以帮助解决此问题)。它们可能与工作效率非常低下。要按 ID 查找对象,必须搜索整个向量。你可以通过利用 "map" / "unordered_map" / "vector" 创建一个查找表,其中键是 ID,值是对象指针或向量中的索引,以减少查询时间。

在我的情况下,通过ID查找元素并不成问题,因为它们可以在向量中对应位置上找到。 - dani
@dani 好的,我以为您说区分每个对象的是其ID而不是在向量中的位置。既然如此,那您就没问题了。唯一的缺点是,您的数据结构相当固定,无法轻松删除对象或重新排序它们。 - Chris Drew
好的,如果我使用ID,我可以重新排序它们。我不会销毁或创建新对象,只是在整个程序中将它们彼此分配。 - dani

0

另一种选择是使用 std::map<Baby, Toy>/std::map<Toy, Baby> 或者甚至是 std::unordered_map<Baby, Toy>/std::unordered_map<Toy, Baby>

#include <map>

std::map<Baby, Toy> babyMap;
std::map<Toy, Baby> toyMap;

// ...

babyMap[theBaby] = theToy;
toyMap[theToy] = theBaby;

如果“宝宝”喜欢多个玩具,或者反之亦然,您可以使用std::map<Baby, std::set<Toy>>s/std::map<Toy, std::set<Baby>>
附注:通常,类似于int的ID是糟糕的代码味道,并且可能会导致严重问题。

-1

抱歉,在您的问题中我读到:

现在,每个婴儿都有一个偏爱的玩具,每个玩具都有一个偏爱的婴儿。


@ KemyLand - 对不起,这不是一个答案,而是我想要在我的之前的回答中添加的评论(我是新来的,我在英语方面有一些困难,我刚刚通过阅读支持中心>回答中学习了规则)。 - P. Sarrapochiello

-1
这个结构体的其中一个向量怎么样?
struct BabyToy { Baby B;  Toy T;};

or

class BabyToy
{
  public:
  Baby B;
  Toy T;

  BabyToy(Baby b, Toy t)
  {
     B=b;
     T=t;
  }
};

问题没有说明一个玩具是否更喜欢同一个喜欢它的婴儿,或者只有一个婴儿喜欢一个玩具。 - Ben Voigt
@Ben Voigt - 你说得对,我的错误是由于对问题的误解以及我的糟糕英语造成的:我认为婴儿和玩具之间是一对一的关系...无论如何,我是这个网站上的新手,我为我的肤浅和匆忙的回答道歉...将来我会尽力仔细阅读问题,在理解问题后再给出我的答案。PS:我现在添加了这条评论,因为当我提供答案时,我刚刚注册,并且还不知道所有规则(以及被投反对票的风险!) - P. Sarrapochiello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接