在子类中,我需要复制基类中的字段。一个简单的例子:如果我们有一个基类Car
,我想制作一辆名为DoubleCar
的汽车,它代表两辆汽车合二为一(有两个发动机,8个车轮等)。这个DoubleCar
就像一辆汽车(我们可以开始它,加速,刹车等),所以做一个继承似乎很自然。我试着用以下方式做到这一点
class Engine{
public: void Start(){}
};
class Car
{
Engine* engine;
public:
Car(Engine* engine){this->engine=engine;}
virtual void Start(){engine->Start();}
};
创建DoubleCar
,其中第一辆车来自基类,secondCar
为字段:
class DoubleCar : public Car
{
Car* secondCar;
public:
DoubleCar(Engine* e1, Engine* e2) : Car(e1)
{secondCar = new Car(e2);}
virtual void Start(){Car::Start(); secondCar->Start();}
};
这个解决方案看起来很难看,似乎一辆车比另一辆更重要。我也尝试将两辆车放在字段中并忽略基本成员,比如这个
class DoubleCar1 : public Car
{
Car *firstCar, *secondCar;
public:
DoubleCar1(Engine* e1, Engine* e2) : Car(NULL)
{firstCar = new Car(e1); secondCar = new Car(e2);}
virtual void Start(){firstCar->Start(); secondCar->Start();}
};
这看起来也不是一个好的解决方案。对于这样的问题,什么是好的设计?当然,在我真正的问题中,我很少有Car
的父母和几个孩子,所以我正处于一棵树的中间。
答案 0 :(得分:1)
在我看来,“双车”就像卡车一样“卡车”,你试图强行注入继承关系只是弄乱了你的概念模型。
例如,您的“双车”不包含两辆车。它包含两倍于普通汽车的发动机和两倍的车轮,但它不包含两辆汽车。
我完全失去与Car
的关系,只关注组成那些可重用的组件类型(例如Engine
):
/** Has "car" in the name, but isn't a car. Cars are single-engined. */
class DoubleCar
{
Engine e1, e2;
public:
virtual void Start() { e1.Start(); e2.Start(); }
};
如果您迫切需要一个共享界面,我只需要“车辆”级别,提供纯虚拟Start
以及您拥有的其他任何内容。
答案 1 :(得分:1)
一般来说,继承模型“是一种”关系。通常这是从通用基类到更具体的派生类。例如:汽车是一种车辆。福特野马是一辆汽车。因此,对于您可能最终得到Vehicle的基类的模型,然后是Car的派生类,然后是FordMustang的另一个派生类。
现在,如果我们试图说“双车是一辆车”,那听起来有点奇怪。这不仅仅是一辆车。这是两个。
如果我们说“双车由两辆车组成”,那听起来很合理。因此,最终可能会有一个DoubleCar类有两个Car成员。这更接近你的最后一个想法,但不会来自Car。
此时,如果我正在编写代码,我会开始质疑我的设计。是否有任何理由让DoubleCar继承汽车? “具有相同的成员功能”是不够的。你是否需要通过一个带有Car引用或指针的接口来提供DoubleCar?如果没有,那么也许它根本不应该来自Car。在这种情况下,组合想法起作用,而DoubleCar本质上是一种Car容器。
但是,如果不了解您实际使用情况的具体情况,我不确定是否可以提供更好的想法。