将部分可编辑对象的集合传递给算法
Posted
技术标签:
【中文标题】将部分可编辑对象的集合传递给算法【英文标题】:Passing a collection of partially editable objects to an algorithm 【发布时间】:2015-08-30 18:55:23 【问题描述】:我用一个简单的例子简化了我的问题:想象我管理一个元素集合std::vector<Element>
,每个元素都有几个成员:
struct Element
public:
double foo;
double bar;
;
然后,我想定义一个抽象类BarEvaluator
,用于根据a
的值计算b
的值的算法。我的第一个想法是:
class BarEvaluator
public:
virtual void evaluate(std::vector<Element>& elements) const = 0;
;
据此,我可以实现几种算法,例如,将bar
值计算为foo
值的平方的算法:
class SqrBarEvaluator
public:
virtual void evaluate(std::vector<Element>& elements) const
for(unsigned long int i = 0; i < elements.size(); ++i)
elements[i].bar = elements[i].foo * elements[i].foo;
;
这运作良好。但我认为这不是一个非常好的架构,因为我的算法也能够修改foo
值。我不想那样。
然后我希望能够使用一种“过滤器”将我的集合提供给算法,该“过滤器”允许仅修改每个元素中的 bar
变量而不是 foo
变量。 C++98 可以吗?我不知道该怎么做。
备注 1: 我不想在 Element
中使用 public
或 private
。你可以想象我也想创建算法FooEvaluator
从bar
值计算foo
值,写访问foo
而不是bar
。
备注2:该算法可以要求所有的集合来计算每个值。
【问题讨论】:
这不正是protected、private和getter/setter方法的概念存在的原因吗? 不,我不想限制每个人访问Element
,只是为了算法。
你为什么使用 C++98?
在一般情况下,正如您所描述的那样,// DO NOT MODIFY .foo OR A CADUCHON WILL COME AFTER YOU
确实是最好的解决方案。 C++ 会提供涉及另一层抽象的各种解决方案,但我建议不要在这种情况下使用它们。
:-) 当然,文档也可以是一种解决方案。我虽然关于集合的代理,但它看起来很丑陋并且实现起来非常复杂。
【参考方案1】:
也许你应该把循环拉出界面。
class BarEvaluator
public:
virtual double evaluate(const Element& element) const = 0;
;
class SqrBarEvaluator
public:
virtual double evaluate(const Element& element) const
return element.foo * element.foo;
;
那你这样称呼它:
std::vector<Element> elements;
...
for (std::vector<Element>::iterator it = elements.begin(); it != elements.end(); ++it)
it->bar = barEvaluator.evaluate(*it);
【讨论】:
其实算法可以要求所有集合计算bar
的值。示例:一种计算与其他值均值的距离的算法。我真正的问题就是这种情况。
@Caduchon:这是一个两步过程。 1)迭代计算平均值。 2)迭代并计算距离。两者都可以用算法解决。
在这种情况下,算法类不能是const。
你的意思是实例?为什么这是个问题?【参考方案2】:
您可以使用包装器:
class BarElementWrapper
public:
BarElementWrapper(Element& e) : elem(e)
double getFoo() return elem.foo;
void setBar(double b) elem.bar = b;
private:
Element& elem;
然后你的算法会收到一个 BarElementWrapper 的集合。
【讨论】:
以上是关于将部分可编辑对象的集合传递给算法的主要内容,如果未能解决你的问题,请参考以下文章