这可能是微不足道的,但我似乎无法找到一种优雅的方式来实现这样的事情。
请考虑以下示例代码:
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()
构造函数。
答案 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) {}
};
基类的更改现在都可以在一个地方完成,即基类构造函数及其选项类,而无需触及所有派生类。