以维护友好的方式实现许多类似的(子)类

时间:2017-04-09 17:11:55

标签: c++ inheritance constructor

这可能是微不足道的,但我似乎无法找到一种优雅的方式来实现这样的事情。

请考虑以下示例代码:

class Fruit {
    int m_weight;
    int m_color;
    int m_price;
  public:
    Fruit(int weight, int color, int price)
      : m_weight(weight)
      , m_color(color)
      , m_price(price)
    {}
}

class Apple : Fruit {
    int m_apple_specific;
  public:
    Apple(int weight, int color, int price, int apple_specific)
      : Fruit(weight, color, price)
      , m_apple_specific(apple_specific)
    {}
}

class Pear : Fruit {
    int m_pear_specific;
  public:
    Apple(int weight, int color, int price, int pear_specific)
      : Fruit(weight, color, price)
      , m_pear_specific(pear_specific)
    {}
}

[...]

static Fruit parseFruit(InputData input) {
  Fruit parsed_fruit;
  if (input.name == 'apple')
    parsed_fruit = Apple(input.weight, input.color, input.price, input.apple_specific);
  else if (input.name == 'pear')
    parsed_fruit = Pear(input.weight, input.color, input.price, input.pear_specific);
  return parsed_fruit
}

在我的示例中,我有一个基类,它结合了常见属性和许多更专业的子类。现在我对这段代码有两个顾虑:

  • 我不喜欢的是我必须为每个子类复制基类构造函数(在我的实际代码中,它们显然有点复杂)。有没有更简单的方法呢?
  • 真正让我渴望更优雅的解决方案:考虑我现在想要将成员m_origin添加到Fruit ......因此我必须调整所有子类!

这真的是它的意思,还是我采取了完全错误的做法?

P.S。不要假设输入数据始终处于方便的输入数据中。对象(然后我可能只是重新设计我的Fruit构造函数),但有时可能需要直接使用Apple()Pear()构造函数。

1 个答案:

答案 0 :(得分:2)

一般指南,也有助于你的情况,每当构造函数获得太多参数时,你可能想要一个单独的“选项”类:

struct FruitParams {
  int weight;
  int colour;
  int price;
};

class Fruit {
  public:
    explicit Fruit(FruitParams params)
        : weight_(params.weight)
        , colour_(params.colour)
        , price_(params.price) {}

    // ...
};

您还可以将选项类设为成员类型(Fruit::Params)。

然后,所有派生的构造函数都采用以下简单形式:

class Apple : public Fruit {
  int apple_specific_;

public:
  Apple(FruitParams params, int a) : Fruit(params), apple_specific_(a) {}
};

基类的更改现在都可以在一个地方完成,即基类构造函数及其选项类,而无需触及所有派生类。