具有 Boost 和外部数据源的享元
Posted
技术标签:
【中文标题】具有 Boost 和外部数据源的享元【英文标题】:Flyweights with Boost and external data sources 【发布时间】:2012-01-13 16:39:16 【问题描述】:也许有一个我没有看到的简单方法,所以希望有人可以向我解释。
假设我有一堂课:
class A
public:
const double parameter;
const std::string name;
const std:: string fileName;
A(const double parameter, const std::string name, const std::string fileName) :
parameter(parameter), name(name), fileName(fileName) ;
;
该类的生成器是:
class AReader
public:
ifstream dataFile;
AReader(const std::string filename);
A* readObject(const std::string objectName);
;
我想使用boost::flyweight
来处理这些A
对象,因为可能会有数百万个对它们的引用,而实际上它们包含大量数据。它们将在name
和fileName
上一起进行哈希处理。
我需要什么来完成这项工作?我需要boost::flyweight
来调用AReader.readObject
并散列/存储生成的A
类。
AReader
是否需要成为完整工厂并用作定制工厂?或者是否可以在享元中使用默认工厂并以某种方式使用AReader
生成A
实例(而不是实现工厂所需的整个存储模式),也许可以通过将AReader
实例作为参数在蝇量级的东西?或者是否有可能从外部数据源获取const
公共变量(即一旦设置,它们就不会改变)而不求助于第二类?
编辑
我也愿意接受其他不使用 Boost 的建议。我当然可以编写自己的轻量级实现,或者如果有更适合的任何其他模式。但是,如果我可以使用已经存在的东西,那将是最好的。无论什么都能最大限度地减少我需要编写的代码量,因为与往常一样,截止日期很短。
【问题讨论】:
【参考方案1】:我没有使用过 Boost::flyweight,但至少从外观上看,键必须是 Assignable
(除了 EqualityComparable
和 Hashable
)。对于您的const
成员,您输入的显然是不是 Assignable
。从外观上看,如果您有密钥提取器,则不必将其设为Assignable
。使用密钥提取器,密钥只需为Assignable
。
【讨论】:
处理将A
放入flyweight 需要做的事情(键提取器而不是可分配的),但这是使用生成A
的帮助器类的唯一方法。一个成熟的工厂供享元使用(实现所需的存储和其他方法)?【参考方案2】:
在您的情况下使用享元的基本方法是让 readObject 返回一个享元。 在内部,readObject 创建一个全新的对象,当您创建相应的享元对象时,它会检查该对象是否已经在享元存储中。如果是这样,它将删除您的新对象,并返回一个引用存储中对象的享元。如果没有,它会将新对象添加到其池中。
现在,这应该很容易实现,但根据您的用例可能效率低下。为获得更好的性能,您可以使用key_value 功能,该功能允许您通过对象的键引用对象,并且仅在存储中不存在它们时才创建它们。
【讨论】:
【参考方案3】:虽然key_value
Flyweight 似乎符合要求,但似乎有一个小问题。
您应该能够通过仅使用密钥类型的一个参数 (key_value flyweights) 来构造 key_value
Flyweight。因此,要使其与您想要的密钥(文件名+名称)一起使用,您必须将这 2 个字段合并为一个(tuple?甚至不确定这是否可行。)
假设您有兴趣以最少的工作获得最大的收益,为什么不只是 Flyweight
类中的字符串,如 Flyweight Basics 中所示?
这意味着A
对象不会按照您想要的方式进行散列,但字符串很容易被加权,并且这些似乎是您的内存问题字段。 (除非这是过于简单化)
【讨论】:
以上是关于具有 Boost 和外部数据源的享元的主要内容,如果未能解决你的问题,请参考以下文章