gpt4 book ai didi

c++ - 存储许多关系 1 :1 between various type of objects : decoupling & high performance

转载 作者:IT老高 更新时间:2023-10-28 23:00:19 27 4
gpt4 key购买 nike

我有 300 多个类(class)。它们在某些方面是相关的。

为简单起见,所有关系都是 1:1。
这是一个示例图。

enter image description here (在实际情况下,大约有 50 个关系对。)

注意:在某些情况下,某些关系可能不存在。
例如,一些 hen 与任何 food 无关。

注意 2: 没有链接 = 从不,例如每个 egg 都与任何 cage 无关。
这种关系永远不会被添加/删除/查询。

问题:

如何优雅地存储它们之间的关系?
我的所有 4 个想法(如下)似乎都有缺点。

Here是一个相关的问题,但具有 1:N 且只有 1 个关系。

我的糟糕解决方案

这些是半伪代码。

版本 1 直接

我的第一个想法是相互添加指针。

Chick.h:-

class Egg;
class Food;
class Chick{ Egg* egg; Food* food;}

Hen.h:-

class Egg; class Cage; class Food;
class Hen{ Egg* egg; Cage* cage; Food* food;}

添加/删除关系和查询非常便宜,例如:-

int main(){
Hen* hen; ... Egg* egg=hen->egg;
}

效果很好,但是随着程序的增长,我想将它们解耦。
粗略地说,Hen.h 不应该包含单词 Egg,反之亦然。

有很多想法,但似乎没有一个很好。
我将为每个解决方法展示一个简短的片段,然后在问题的末尾总结利弊。

版本 2 HashMap

使用 std::unordered_map
它成为我程序的瓶颈。 (在 Release模式下分析)

class Egg{}; class Hen{};  //empty (nice)
.....
int main(){
std::unordered_map<Hen*,Egg*> henToEgg;
std::unordered_map<Egg*,Hen*> eggToHen;
....
Hen* hen; ... Egg* egg=henToEgg[hen];
}

版本 3 中介者单

将每个关系存储在每个实体的单个大中介中。
为空槽浪费大量内存(例如 EgghenFood_hen 槽)。
每个实体中的总浪费 = type-of-relation-pair*2*4 字节(如果以 32 位运行)。

class Mediator {
Egg* eggHen_egg=nullptr;
Hen* eggHen_hen=nullptr;
Hen* henFood_hen=nullptr;
Food* henFood_food=nullptr;
//... no of line = relation * 2
};
class Base{public: Mediator m;};
class Egg : public Base{}; //empty (nice)
class Hen : public Base{};
int main(){
Hen* hen; ... Egg* egg=hen->eggHen_egg;
}

版本 4 Mediator-array(类似于 3)

尝试标准化 - 高度灵活。

class Mediator {
Base* ptrLeft[5];
Base* ptrRight[5];
};
class Base{public: Mediator m;};
class Egg : public Base{}; //empty (nice)
class Hen : public Base{};
int main(){
enum RELA_X{RELA_HEN_EGG,RELA_HEN_CAGE,RELA_EGG_CHICK, .... };
Hen* hen; ...
Egg* egg=hen->m.ptrRight[RELA_HEN_EGG];
//^ get right of "hen-egg" === get "egg" from "hen"
//^ can be encapsulated for more awesome calling
}

优点和缺点

绿色(+)很好。红色 (-) 不好。 enter image description here

编辑:我正在使用 Entity-Component对于 60fps 的游戏。
它是一个持久数据库:一个用于游戏整个生命周期的单个实例。

Edit2: 所有关系都是弱关系,而不是 is-a 或强 std::unique_ptr 所有权。 (感谢沃尔特)

  • 一只母鸡 一个笼子
    有些hens 不在任何cage 中,有些cage 是空的。
  • 一个chick 来自一个鸡蛋
    然而,有些小鸡并非来自任何(它们只是从天上掉下来的),
    还有一些eggs没有幸运成为chick
  • 一只母鸡和一只小鸡正在吃一盘(可能相同)food
    一些 food 盘子刚刚准备好,但没有提供。

Edit3:为每个对象分配一个整数 id 是个好主意。
(感谢 Oliv、ahoxha 和 Simone Cifani)

Edit4:: 无需提供可编译的代码,只需一个基本部分/概念就足够了。

最佳答案

根据要求,如果您只有一对一的关系,那么在我看来它就像一个图表。在这种情况下,如果它人口稠密(有很多关系),我会使用图的矩阵表示。在下表中,我将数字 0 到 4 分别与实体(母鸡、笼子、食物、鸡蛋和小鸡)相关联。如果存在 Hen - Egg 关系,则矩阵在 matrix[0][3] 的位置将为 1,如果不存在,则值为 0(您可以选择您选择决定如何判断关系何时存在或不存在)。如果关系是无向的,那么您只需要矩阵的一侧(例如上三角形)。

+---------------------------------+
| Hen | Cage | Food | Egg | Chick |
+---------------------------------+
| 0 | 1 | 2 | 3 | 4 |
+---------------------------------+

0 1 2 3 4
+--------------------+
0 | 0 | 1 | 0 | 1 | 1 |
+---+---+---+---+----+
1 | 0 | 0 | 0 | 1 | 1 |
+---+---+---+---+----+
2 | 0 | 0 | 0 | 0 | 1 |
+---+---+---+---+----+
3 | 0 | 0 | 0 | 0 | 1 |
+---+---+---+---+----+
4 | 0 | 0 | 0 | 0 | 0 |
+--------------------+

这个解决方案的缺点隐藏在内存使用中,特别是如果矩阵包含很多 0(不存在的关系);您将不必要地占用大量空间。在这种情况下,您可以使用 linked-list representation of the graphs .

关于c++ - 存储许多关系 1 :1 between various type of objects : decoupling & high performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43383088/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com