有没有比这更有效的结构/模式C ++方法?

时间:2012-01-14 02:41:02

标签: c++

基本的想法是,我有一个类的“家庭”,它们都做同样的事情,但方式略有不同。这个“家庭”用于“高性能”循环,因此速度至关重要。此外,特定系列由配置文件...

指定

问题是这里的主要功能中存在巨大的代码重复。有没有更好的方法来构建这个,所以我不必写三次HP<objx> testtest.loop(bobloblaw)? (实际上,这段代码的行多于2行......)

class obj1 {
public:
    double f(double x) const { return 1.; }
};

class obj2 {
public:
    double f(double x) const { return x; }
};

class obj3 {
public:
    double f(double x) const { return x*x; }
};

template <class O>
class HP {
private:
    O obj;

public:

    double loop(const vector<double>& x) {
        double s = 0.;
        for (auto i : x) s += obj.f(i);

    return s;
    }
};

int main() {
    string config = "bob";
    double result = 0;
    vector<double> bobloblaw;

    /* Read configuration file to determine which object to use. */
    if (config == "obj1") {
        HP<obj1> test;
        result = test.loop(bobloblaw);
    } else if (config == "obj2") {
        HP<obj2> test;
        result = test.loop(bobloblaw);
    } else if (config == "obj3") {
        HP<obj3> test;
        result = test.loop(bobloblaw);
    }

    return result;
}

2 个答案:

答案 0 :(得分:4)

以下是未经测试的,但应该有效:

class obj1
{
public:
  double f(double x) const { return 1.; }
};

class obj2
{
public:
  double f(double x) const { return x; }
};

class obj3
{
public:
  double f(double x) const { return x*x; }
};

class HPbase
{
public:
  virtual double loop(const vector<double>&) = 0;
};

template <class O> class HP:
  public HPbase
{
public:
  double loop(const vector<double>& x)
  {
    double s = 0.;
    for (auto i : x)
      s += obj.f(i);
    return s;
  }
private:
  O obj;
};

std::unordered_map<std::string, std::unique_ptr<HPbase>> decode{
  {"obj1"}, new HP<obj1>()},
  {"obj2"}, new HP<obj2>()},
  {"obj3"}, new HP<obj3>()} };

int main()
{
  string config = "bob";
  double result = 0;
  vector<double> bobloblaw;

  /* Read configuration file to determine which object to use. */
  result = decode[config].loop(bobloblaw);
}

请注意,唯一添加的是HP<>的基类和替换代码的if / else逻辑的地图。

答案 1 :(得分:3)

难道你不能让这3个类都是同一个父类的子类吗? main仍然需要使用正确的子类分配给测试,但测试本身将被声明为常见的超类。

这里的缺点是可能存在(可能很小的)性能损失,因为编译器不知道何时为test.loop生成将使用哪个版本的代码,因此必须在运行时决定。

另一种可以解决这个问题的方法是将公共代码编写为宏,因此只能编写一次但扩展为3个不同的副本,编译器可以根据测试的变体优化每个副本正在使用。可以使调试成为一个婊子,但如果你的重点是性能和减少源的冗余(而不是对象的冗余),这可能是一个很好的权衡。