减少类层次结构

时间:2018-01-17 08:05:53

标签: c++11 constructor

在我们的代码中有一个带有虚函数的类层次结构。我们有不同 “图表”根据相同类型的参数产生一组固定的数字。 细节不同,但行为是一样的。

我们对动态多态作为一种模式感到满意,我们并不那么喜欢所有 我们必须用C ++ 11编写的样板代码才能实现它。我大部分都是 对构造函数中的重复感到沮丧。

类层次结构如下所示:

enter image description here

有一个基地,两个中间人和很多孩子。基地和中间人 有非平凡的构造函数,孩子们不需要任何更多的参数。然而,我们 必须在子代中生成构造函数,因为默认构造函数不会 正确构建中间体。

这是代码,仅限于构造函数,析构函数和成员。该 Diagram课程:

class Diagram {
public:
  Diagram(std::vector<CorrInfo> const &corr_lookup)
      : corr_lookup_(corr_lookup) {}

  virtual ~Diagram() {}

private:
  std::vector<CorrInfo> const &corr_lookup_;
};

中级DiagramNumeric<>类:

template <typename Numeric_>
class DiagramNumeric : public Diagram {
public:
  using Numeric = Numeric_;

  DiagramNumeric(std::vector<CorrInfo> const &_corr_lookup,
                 std::string const &output_path,
                 std::string const &output_filename,
                 int const Lt)
      : Diagram(_corr_lookup),
        output_path_(output_path),
        output_filename_(output_filename),
        Lt_(Lt),
        correlator_(corr_lookup().size(), std::vector<Numeric>(Lt, Numeric{})),
        c_(omp_get_max_threads(),
           std::vector<std::vector<Numeric>>(
               Lt, std::vector<Numeric>(corr_lookup().size(), Numeric{}))) {}

private:
  std::string const &output_path_;
  std::string const &output_filename_;

  int const Lt_;

  std::vector<std::vector<Numeric>> correlator_;
  std::vector<std::vector<std::vector<Numeric>>> c_;
};

其中一个孩子,C2c

class C2c : public DiagramNumeric<cmplx> {
public:
  C2c(std::vector<CorrInfo> const &corr_lookup,
      std::string const &output_path,
      std::string const &output_filename,
      int const Lt);
};

C2c::C2c(std::vector<CorrInfo> const &corr_lookup,
         std::string const &output_path,
         std::string const &output_filename,
         int const Lt)
    : DiagramNumeric<cmplx>(corr_lookup, output_path, output_filename, Lt) {}

当我需要在中间体的构造函数中添加另一个参数时,我必须这样做 更改DiagramNumeric<>声明和每个子声明和定义。 这会使2 * N + 1个孩子发生N更改,感觉非常糟糕。

我考虑将struct设为DiagramNumeric<>::CtorParams,这只是 通过传递。需要调整C2c实例化的客户端代码,但是 我们实际上只传递了不同的corr_lookup参数,其余三个都是 同样的。

是否有一些机制可以用来削减其中很大一部分 样板代码?

1 个答案:

答案 0 :(得分:1)

  

我们对动态多态作为一种模式感到满意,....我是   对构造函数中的重复感到沮丧。

这不是一些c ++ 11错误。 问题直接来自动态多态。尤其是每个儿童班都需要建立其父母。

您拥有的替代方案是依赖注入+静态多态:

  1. 您有以Diagram模板作为参数
  2. 的类和方法
  3. 您不再拥有一个Diagram类 (静态多态性)
  4. C2c和其他类不再构造DiagramNumeric<cmplx>,而只是接收一个作为参数复制到成员变量。 ( 依赖注入
  5. 你最终会得到

    class C2c {
    public:
      explicit C2c(const DiagramNumeric<cmplx> &diagram_numeric) 
      : diagram_numeric_(diagram_numeric) {}
    
    private :
       DiagramNumeric<cmplx> diagram_numeric_;
    };
    

    假设您要添加另一个参数。在最好的情况下,这是依赖类别的O(1)变化。在最坏的情况下,如果你有一个构建函数,例如

    ,它会回到2 * N + 1更改
    C2c build(std::vector<CorrInfo> const &corr_lookup,
          std::string const &output_path,
          std::string const &output_filename,
          int const Lt)
    {
        return C2c(DiagramNumeric<cmplx>(corr_lookup, output_path, output_filename, Lt));
    }