如何从基类c ++复制字段

时间:2014-01-12 17:37:06

标签: c++ inheritance

在子类中,我需要复制基类中的字段。一个简单的例子:如果我们有一个基类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的父母和几个孩子,所以我正处于一棵树的中间。

2 个答案:

答案 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容器。

但是,如果不了解您实际使用情况的具体情况,我不确定是否可以提供更好的想法。