我有一个“项目”,它的数据可以用3种方式表示。我可以以运行时成本从一种表示转换为其他任何一种表示。一旦我完成了转换,我想保留新的表示形式。数据的任何表示都可以转换为任何其他表示形式,而无需“修改”核心数据。由于运行时的成本,我想要一个包含3种数据表示的类。在任何时候,其中1到3将是有效的。
这一点的真正原因在于它也有访问方法,用户可以在其中要求一些东西。这个东西可以从一个或更多的表示中得到。例如,您可以从representation1获得“范围”,从表示2或3获得“卷”。
我的解决方案是以3种表示形式创建类作为成员数据(以及一种知道它们是否有效的方法)。然后,我创建了一个getRange()方法,在内部知道它需要哪种表示,并在必要时创建它。这很好地解决了我的所有问题,除了get方法不能是const之外。
因此,这个解决方案的真正问题是,即使这个类的“常量”实例也不是真正的const,因为它可能在内部创建其他表示。但是,它实际上是“常量”,因为更改表示不会修改核心数据。
是否有一个C++设计模式可以帮助这个类?有什么建议吗?
发布于 2016-04-29 15:08:07
我的解决方案是以3种表示形式创建类作为成员数据(以及一种知道它们是否有效的方法)。然后,我创建了一个getRange()方法,在内部知道它需要哪种表示,并在必要时创建它。这很好地解决了我所有的问题,,除了get方法不能是const之外。
这正是指定的mutable类型的目的所在!为了能够在仍然拥有const方法的同时更新内部表示,将表示属性设置为mutable。
struct A {
int get_range() const {
if (!_repr2.is_valid()) {
_repr2 = Repr2(_repr1); // I am in a const method, but still
// I can update a mutable attribute
}
return _repr2.get_range();
}
private:
mutable Repr1 _repr1;
mutable Repr2 _repr2;
};这里是一个完整的示例,它有两个表示形式,它们使用std::unique_ptr来存储表示,这样您就可以轻松地检查其中一个是否被实例化。
发布于 2016-04-29 15:14:40
根据霍尔特的回答,可变是这里需要的主要东西。您还可以从存储表示形式的boost::optional中获益。这有助于“知道它们是否有效”这部分问题:
struct A {
int get_range() const {
if (!_repr2) {
_repr2 = Repr2(*_repr1);
}
return _repr2->get_range();
}
private:
mutable boost::optional<Repr1> _repr1;
mutable boost::optional<Repr2> _repr2;
};https://stackoverflow.com/questions/36941690
复制相似问题