很抱歉,如果之前有人问过这个问题,我不太清楚这个术语,也不太清楚该如何问这个问题。
我想知道是否有在C++中实现对象模型的库或最佳实践。如果我有一组类,这些类的实例可以相互关联,并且可以通过各种方法相互访问,那么我想选择一组良好的底层数据结构来管理这些实例及其相互关系。这在Java中很容易,因为它为我处理内存分配和垃圾收集,但在C++中,我必须自己处理。
HTML的文档对象模型 (DOM)就是一个例子;作为另一个(人为的)例子,假设我有以下类:
EntityPerson (Entity的子类)Couple (Entity的子类)PropertyHouse (Property的子类)Pet (Property的子类)Car (Property的子类)这些关系是:
Entity home的House类pets的Petcars的Carchildren的Person
Person spouse的类Personmarriage的类Coupleparents的类Entity (在这个模型中,如果他们不活着,父母就不存在!)
Couple members的Person类
Property owner的Entity类
现在我已经考虑了这些对象和它们之间的关系,我想开始创建数据结构、方法和字段来处理它们,这就是我迷失的地方,因为我必须处理内存分配和生命周期管理等等。您可能会遇到以下问题:我可能希望将一个对象放入std::map或std::vector中,但如果这样做,就无法存储指向这些对象的指针,因为它们可以在地图或向量增长或缩小时重新定位。
当我经常使用COM时,我使用的一种方法是拥有一个包含所有内容的隐藏集合。集合中的每个对象都有一个唯一的ID (数字或名称),可以从集合中查找它,并且每个对象都有指向集合的指针。这样,如果有一个对象想指向另一个对象,而不是字面上持有指向另一个对象的指针,我会存储ID并通过隐藏的集合查找它。我可以使用引用计数来自动处理生命周期问题(除了周期不相交的情况外,有时这不是一个问题)。
还有其他方法吗?或者,在C++中是否有库可以使这类事情变得更容易呢?
编辑:然后还有其他问题,例如在许多情况下,对象之间的关系可能是可变的,您必须预先考虑如何存储对对象的引用,以及应该提供哪些方法来访问彼此的对象。例如,如果我有一个Person X的句柄,并且我想要表示“查找X的名为George”的概念,那么我必须存储"George“的名称,而不是一个子数字:子级可以存储在一个向量中,并且我可以调用X.getChildCount()和X.getChild(0),但是"George”可能并不总是子编号0,因为在子向量中的"George“之前可以插入其他的子节点。或者X可能有两三个或四个孩子,也就是“乔治”。或者“乔治”可以改名为“安东尼”或“乔治娜”。在所有这些情况下,最好使用某种唯一的不可变ID。
编辑2: (等我把问题弄清楚了,我就可以处理方法和属性名称的选择,我可以处理是否使用地图、列表或向量)。这很简单。我特别想解决的问题是:
发布于 2009-04-29 16:39:02
您写过关于将对象模型中的对象存储在std::vector等中的内容,以及使用指向它们的指针时遇到的问题。这提醒我,将C++类分为两类是很好的(我不确定这里的术语是什么):
有很多很好的理由来打破以上的规则。但我发现,从一开始就忽略它们会导致程序不可读、不可靠(尤其是在内存管理方面),并且很难维护。
现在回到你的问题上。
如果您想要存储一个具有复杂关系的数据模型,并且执行诸如“查找X的子级名为George”之类的查询,为什么不考虑一些内存中的关系数据库呢?
注意,当您要有效地实现( a)更复杂的双向关系和( b)基于不同对象属性的查询时,您可能需要创建与关系数据库内部非常相似的索引数据结构。您的实现(在单个项目中会有很多)真的会更有效和更健壮吗?
“所有事物的集合”和对象ids也是如此。无论如何,您需要跟踪对象之间的关系,以避免没有对象的ids。它和指针有什么不同?其他的则得到有意义的错误,而不是在整个记忆中疯狂,也就是说;-)
内存管理的一些想法:
发布于 2009-04-29 14:56:24
这方面有大约一百万种方法(据保守估计)。你真的在问“如何在C++中设计软件”。答案是,恐怕“你的软件会做什么?”--仅仅知道你想和人和房子打交道是不够的。
发布于 2009-04-29 15:06:49
这不就是OOP的重点吗?您要求的是实现细节,隐藏在这些类的公共接口后面,因此不必担心,因为您可以更改它而不更改接口?所以去吧,按你的建议去做吧。然后,如果存在性能、内存或其他问题,则可以在不破坏其余代码的情况下修复实现。
在我看来,将数据存储在数据库中并使用某种对象-关系映射可能是另一种选择。
https://stackoverflow.com/questions/802706
复制相似问题