通过唯一的成员 ID 来标识对象是个好主意吗?
Is it a good idea to identify objects by an unique member id?
我的问题是,我应该如何将对象相互关联起来。
我有两个向量,vector<Baby> babies
和 vector<Toy> toys
。每个婴儿和每个玩具都有一个独特的成员int id
。因此所有的婴儿和玩具都从0到n编号。
现在,每个宝宝都有一个喜欢的玩具,每个玩具都有一个喜欢的宝宝。到目前为止,我使用的是指针:Baby 有一个指向他喜欢的 Toy 的指针,而这个 Toy 有一个指向 Baby 的指针。 (没关系,因为我永远不会改变向量)
但是,区分婴儿和玩具的是它们的 ID,而不是它们在向量中的位置。
随着我的相处,我质疑我的设计,发现指针是有效的,但它们可能会在未来导致问题。相反,如果我使用 ID 就可以了,但我需要访问整个婴儿或玩具载体。
在这种情况下有没有普遍的做法?使用指针是个好主意吗?我应该编写自己的容器以智能方式使用 ID 吗?
编辑:
我想补充一点,我考虑过一张将婴儿和玩具联系起来的地图。但是,我在运行时确定婴儿与玩具的关系(反之亦然)。找到这种关系是该程序的主要部分。因此我不确定我是否可以使用地图。不过,我会看看它(到现在还没用过)。更重要的是,有关首选玩具和婴儿的信息必须是对象的一部分,而不是(仅)高级数据结构的一部分。
What about a vector of one of this structure?
struct BabyToy { Baby B; Toy T;};
or
class BabyToy
{
public:
Baby B;
Toy T;
BabyToy(Baby b, Toy t)
{
B=b;
T=t;
}
};
另一种方法是使用 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;
如果 Baby
"happens" 喜欢不止一种玩具,反之亦然,您可以使用 std::map<Baby, std::set<Toy>>
s/std::map<Toy, std::set<Baby>>
.
P.D:通常,int
风格的 ID 是一种糟糕的代码味道,以后可能会导致严重的问题。
抱歉,但在您的问题 J 中阅读:
Now, each Baby has one preferred Toy and each Toy has a preferred
Baby.
为关系使用唯一 ID 有一些优势。 ID 不能像指针那样悬空,也不能像向量索引那样越界。它们可以很容易地序列化。当向量被重新分配或重新排序时,它们不会失效。
但它们也有一些缺点。由您来确保它们保持唯一性(使用 GUID 可以帮助做到这一点)。他们的工作效率也可能非常低。要按 ID 查找对象,您必须搜索整个向量。您可以遍历向量以创建查找 map
/unordered_map
/vector
,其中键是 ID,值是指向向量中对象或索引的指针。
我的问题是,我应该如何将对象相互关联起来。
我有两个向量,vector<Baby> babies
和 vector<Toy> toys
。每个婴儿和每个玩具都有一个独特的成员int id
。因此所有的婴儿和玩具都从0到n编号。
现在,每个宝宝都有一个喜欢的玩具,每个玩具都有一个喜欢的宝宝。到目前为止,我使用的是指针:Baby 有一个指向他喜欢的 Toy 的指针,而这个 Toy 有一个指向 Baby 的指针。 (没关系,因为我永远不会改变向量) 但是,区分婴儿和玩具的是它们的 ID,而不是它们在向量中的位置。
随着我的相处,我质疑我的设计,发现指针是有效的,但它们可能会在未来导致问题。相反,如果我使用 ID 就可以了,但我需要访问整个婴儿或玩具载体。
在这种情况下有没有普遍的做法?使用指针是个好主意吗?我应该编写自己的容器以智能方式使用 ID 吗?
编辑: 我想补充一点,我考虑过一张将婴儿和玩具联系起来的地图。但是,我在运行时确定婴儿与玩具的关系(反之亦然)。找到这种关系是该程序的主要部分。因此我不确定我是否可以使用地图。不过,我会看看它(到现在还没用过)。更重要的是,有关首选玩具和婴儿的信息必须是对象的一部分,而不是(仅)高级数据结构的一部分。
What about a vector of one of this structure?
struct BabyToy { Baby B; Toy T;};
or
class BabyToy
{
public:
Baby B;
Toy T;
BabyToy(Baby b, Toy t)
{
B=b;
T=t;
}
};
另一种方法是使用 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;
如果 Baby
"happens" 喜欢不止一种玩具,反之亦然,您可以使用 std::map<Baby, std::set<Toy>>
s/std::map<Toy, std::set<Baby>>
.
P.D:通常,int
风格的 ID 是一种糟糕的代码味道,以后可能会导致严重的问题。
抱歉,但在您的问题 J 中阅读:
Now, each Baby has one preferred Toy and each Toy has a preferred Baby.
为关系使用唯一 ID 有一些优势。 ID 不能像指针那样悬空,也不能像向量索引那样越界。它们可以很容易地序列化。当向量被重新分配或重新排序时,它们不会失效。
但它们也有一些缺点。由您来确保它们保持唯一性(使用 GUID 可以帮助做到这一点)。他们的工作效率也可能非常低。要按 ID 查找对象,您必须搜索整个向量。您可以遍历向量以创建查找 map
/unordered_map
/vector
,其中键是 ID,值是指向向量中对象或索引的指针。