jav*_*ver 13 c++ database one-to-one relationship c++14
我有300多个班级.它们在某些方面有关系.
为简单起见,所有关系均为1:1.
这是一个示例图.
注意:对于某些情况,某些关系可能不存在.
例如,某些hen
与任何内容无关food
.
注2:没有链接=从不,例如每个egg
都与任何相关cage
.
永远不会添加/删除/查询这种关系.
如何优雅地存储它们之间的关系?
我的所有4个想法(下面)似乎都有缺点.
这是一个相关的问题,但是1:N只有1个关系.
这些是半伪代码.
我的第一个想法是互相添加指针.
Chick.h: -
class Egg;
class Food;
class Chick{ Egg* egg; Food* food;}
Run Code Online (Sandbox Code Playgroud)
Hen.h: -
class Egg; class Cage; class Food;
class Hen{ Egg* egg; Cage* cage; Food* food;}
Run Code Online (Sandbox Code Playgroud)
添加/删除关系和查询非常便宜,例如: -
int main(){
Hen* hen; ... Egg* egg=hen->egg;
}
Run Code Online (Sandbox Code Playgroud)
它运作良好,但随着我的程序的增长,我想要将它们分离.
粗略地说,Hen.h
不应该包含单词Egg
,反之亦然.
有很多想法,但似乎都没有.
我将展示每个解决方案的简短片段,然后总结问题末尾的利弊.
使用std::unordered_map
.
它成为我程序的瓶颈.(在发布模式下配置)
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];
}
Run Code Online (Sandbox Code Playgroud)
将每个关系存储在每个实体的单个大调解器中.
为空插槽浪费了大量内存(例如Egg
有henFood_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;
}
Run Code Online (Sandbox Code Playgroud)
尝试标准化 - 高度灵活性.
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
}
Run Code Online (Sandbox Code Playgroud)
编辑: 我正在使用Entity-Component进行60fps游戏.
它是一个持久性数据库:用于游戏整个生命周期的单个实例.
编辑2:所有的关系都是弱关系而不是一个或一个强大的std::unique_ptr
所有权.(感谢沃尔特)
hen
是一个cage
.hens
不在cage
,有些cages
是空的. chick
来自一个egg
.chicks
人并非来自任何人egg
(他们只是从天而降),eggs
人没有幸运地成为chick
. hen
和a chick
正在吃一块(可能是相同的)盘子food
.food
盘子刚准备好但没有送达. Edit3:为每个对象分配一个整数id可能是个好主意.
(感谢Oliv,ahoxha和Simone Cifani)
Edit4 ::不需要提供可编译的代码,只需要一个必不可少的部分/概念就足够了.
这个问题没有也不可能有好的答案,因为你的算法未知。一般来说,您希望数据具有局部性,而间接总是破坏它的一种方法。
如果您有一个适用于母鸡的算法,您希望它们尽可能紧密地打包,并且最好在内存中呈线性,以获得最大的缓存命中率。
如果您的算法需要处理母鸡和鸡蛋之间的关系。他们需要是本地人。这不能通过将它们保存为母鸡中的指针来实现,但您需要一个包含所有母鸡 <-> 鸡蛋关系的数组。
你看,这很大程度上取决于你打算做什么。如果你真的想获得高绩效,你就必须防止深度间接。您尝试解析的每个指针都可能会破坏缓存行。如果你的CPU只是追着他们走,性能会很低。