扩展基类并使用功能而不更改派生类

时间:2019-11-30 04:34:30

标签: c++ c++11 inheritance polymorphism

我有一些派生类的C ++基类。如果以后再通过继承扩展基类,则可以用这种方法来反映已经派生的类中的更改。为了使我的问题更清楚,请考虑以下代码。

#include <iostream>

class FourWheelVehicle
{
    public:
        FourWheelVehicle()
        {std::cout<<"FourWheelVehicle created\n";}
};
class Car: public FourWheelVehicle
{
    public:
        Car()
        {std::cout<<"Car created\n";}
};
class Toyota: public Car
{
    public:
        Toyota()
        {std::cout<<"Toyota Car created\n";}
};
class Audi: public Car
{
    public:
        Audi()
        {std::cout<<"Audi Car created\n";}
};
int main()
{
    Toyota t;
    std::cout<<"..............................\n";
    Audi a;
    return 0;
}

如何将FourWheelVehicle扩展到FourWheelVehicleWithSeatBelt,这样我之前派出的所有汽车都将获得安全带而不会更改其代码? 我尝试了以下方法:

           FourWheelVehicle
               /      \
              /        \
             /          \
            Car          \
            /\            \
           /  \            \
      Toyota Audi    FourWheelVehicleWithSeatBelt

class FourWheelVehicleWithSeatBelt: public FourWheelVehicle
{
    public:
        FourWheelVehicleWithSeatBelt()
        {std::cout<<"FourWheelVehicleWithSeatBelt created\n";}
};

以上方案似乎无效!

2 个答案:

答案 0 :(得分:1)

一个类不能从同级类继承。在您的图中,期望Car接受FourWheelVehicleWithSeatBelt的功能就像期望Toyota接受Audi的功能一样。这不会发生。

要在继承链中获得另一个类,新类需要进入链中,而不是新分支中。由于您(由于某种原因)无法更改派生类,因此它们仍必须继承自FourWheelVehicle。这样您就可以看到类似以下内容的内容:

                  ????
                   /
                  /
                 /
           FourWheelVehicle
               /
              /
             /
            Car
            /\
           /  \
      Toyota Audi

对此有一种直接的方法。将您当前的FourWheelVehicle类重命名为其他名称(FourWheelVehicleWithoutSeatBelts?),然后创建一个继承自FourWheelVehicle的新FourWheelVehicleWithoutSeatBelts类,并添加安全带。或者,新的FourWheelVehicle应该同时继承FourWheelVehicleWithoutSeatBeltsVehicleWithSeatBelts类。在该方案中,Vehicle可能是虚拟基类。

命名方案很奇怪,但是由于您不能更改派生类的代码,因此您可能会受其困扰。这是从设计不足开始的危险之一。 (请注意,“不足”并不总是设计者的错。有时是,但有时项目需求会发生不可预测的变化。)

(我个人会尝试获得更改Car定义的权限,以便可以使用更合理的命名方案。Car的子级不需要更改。有时好的程序设计意味着与其他人交谈。)

答案 1 :(得分:0)

在这种情况下,我不确定为什么如果所有派生类都需要修改基类,为什么不这样做呢?但是,如果您仍然希望以这种方式进行操作,则可以使用多个继承来进行操作,例如:

#include <iostream>

class FourWheelVehicle
{
    public:
        FourWheelVehicle()
        {std::cout<<"FourWheelVehicle created\n";}
};
class SeatBelt
{
    public:
        SeatBelt()
        {std::cout<<"Seatbelt created\n";}
};

class Car: public FourWheelVehicle, SeatBelt
{
    public:
        Car()
        {std::cout<<"Car created\n";}
};

这将通过公共继承将安全带和FourWheelVehicle赋予Car

相关问题