将数据添加到实例的最有效方法

时间:2010-03-07 11:40:54

标签: c++ stl class-design

我有一个类,让我们说Person,由另一个类/模块管理,让我们说PersonPool。

我的应用程序中有另一个模块,比如模块M,它希望以最有效的方式将信息与人员关联起来。我考虑了以下备选方案:

  • 将数据成员添加到Person,该应用程序的其他部分可以访问该成员。优点是它可能是最快的方式。缺点是这是非常侵入性的。 Person不需要知道关于这些额外数据的任何信息,如果我想将这个数据成员与其他模块保护起来,我需要将其设为私有,并使模块M成为朋友,我不喜欢。
  • 向Person添加'generic'属性包,其他模块可以添加其他属性。优点是它不具有侵入性(除了具有属性包),并且很容易通过其他模块添加“属性”。缺点是它比直接从Person获取值要慢得多。
  • 在模块M中使用map / hashmap,它将Person(指针,id)映射到我们想要存储的值。对于数据分离而言,这看起来是最佳解决方案,但速度要慢得多。
  • 给每个人一个唯一的号码,并确保在历史记录中没有两个人获得相同的号码(我甚至不想让这些人重复使用号码,因为那时老人的数据可能会混淆一个新人的数据)。然后外部模块可以简单地使用向量将人的唯一编号映射到特定数据。优点是我们不会使用它不需要知道的数据(除了他独特的nubmer)来入侵Person类,并且我们可以快速地从向量中获取模块M的数据。缺点是如果删除和创建了很多人,矢量可能会变得非常大(因为我们不想重复使用唯一的数字)。

在最后一个替代方案中,问题可以通过使用稀疏向量来解决,但我不知道是否有非常有效的稀疏向量实现(比map / hashmap更快)。

还有其他方法可以完成这项工作吗? 或者是否有一个有效的稀疏向量可以解决上一个备选方案的内存问题?

2 个答案:

答案 0 :(得分:2)

我会用map / hashmap计算解决方案,如果它的性能足够好的话,请使用它。否则你别无选择,只能将这些属性添加到类中,因为这是最有效的方法。

或者,您可以创建Person的子类,基本上将所有接口方法转发到原始类,但添加所需的所有属性,并在对M的一些调用期间将原始Person更改为您自己的修改过的。

这样,模块M将看到子类及其所需的所有属性,但所有其他模块都会将其视为Person类的一个实例,并且无法看到您的自定义属性。

答案 1 :(得分:1)

第一种和第三种是相当常见的技术。第二个是动态编程语言如Python和Javascript 如何为对象实现成员数据,所以不要因为不可思议的速度而忽略它。第四个与关系数据库的工作方式相同。使关系数据库像clapper一样运行是可能的,但也很困难。

简而言之,您已经描述了4种广泛使用的技术。判断其中任何一个的唯一方法是使用特定于您的问题的详细信息(所需性能,人数,属性数,代码中要执行此操作的模块数等)以及相应的度量。

另一种可能性是模块M定义一个继承自Person的类,并添加额外的数据成员。这里的原则是M的一个人的想法不同于人的一个人的想法,所以将M的想法描述为一个阶级。当然,这仅适用于在同一个Person对象上运行的所有其他模块通过多态实现的情况,此外,如果M可以负责创建对象(可能通过依赖注入工厂)。这是一个非常大的“如果”。更大的一个,如果除了M之外什么都不需要对对象进行生命循环,那么你可以使用组合或私有继承而不是公共继承。但是,如果模块N要创建人员集合,那么它们都没有用,然后模块M想要为它们附加额外的数据。