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

Passing a collection of partially editable objects to an algorithm

本文关键字:集合 算法 对象 编辑      更新时间:2023-10-16

我用一个简单的例子简化了我的问题:immagine 我管理一个元素集合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:算法可以要求所有集合来计算每个值。

也许你应该把循环拉出接口。

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);
}

您可以使用包装器:

class BarElementWrapper
{
public:
    BarElementWrapper(Element& e) : elem(e) { }
    double getFoo() { return elem.foo; }
    void setBar(double b) { elem.bar = b; }
private:
    Element& elem;
}

然后你的算法会收到一个 BarElementWrapper 的集合。