将部分可编辑对象的集合传递给算法

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 中使用 publicprivate。你可以想象我也想创建算法FooEvaluatorbar值计算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 的集合。

【讨论】:

以上是关于将部分可编辑对象的集合传递给算法的主要内容,如果未能解决你的问题,请参考以下文章

如何在设计师的“收藏编辑器窗口”中制作可编辑的对象?

如何在反应JavaScript中将id传递给navlink

如何将可编辑数据传递给组件?

MVVM 并将可选值传递给 viewModel

可观察值是另一个可观察值的一部分

UITableview 部分可编辑