C ++派生类覆盖基类的成员与另一个派生类?

时间:2013-08-22 21:32:05

标签: c++ inheritance derived-class derived

我有这样的课程:

class ParkingLot
{
public:
    int spaces;
    virtual bool something() { return true; }
}
class ParkingLotBuilding
{
public:
    ParkingLot Floor1, Floor2;
}

我有很多功能可以使用ParkingLotBuilding。让我们说某人(我)来自ParkingLot和ParkingLotBuilding:

class DerivedParkingLot : public ParkingLot
{
public:
    virtual bool something() { return false; }
}
class DerivedParkingLotBuilding : public ParkingLotBuilding
{
public:
    // how can I make it so that Floor1 and Floor2 are for DerivedParkingLot?
}

我有我无法控制的功能,如下所示:

CheckBuilding( ParkingLotBuilding &building )
{
    if(building.Floor1.something() == true)
    // error
}

如果我将DerivedParkingLotBuilding对象传递给该函数,我该怎么做才能调用DerivedParkingLot :: something()来返回false?那可能吗?对不起,如果我没有解释这个权利,我不知道如何询问这个问题。感谢

4 个答案:

答案 0 :(得分:0)

实际上你只是从ParkingLot实例调用DerivedParkingLot函数?

您的代码已经通过将某个方法指定为虚拟来完成它,它将自动搜索其继承树中的最低方法。

测试它的一种简单方法是在ParkingLot和DerivedParkingLot中实现something方法,在每个方法中放入不同的消息并检查它

答案 1 :(得分:0)

您可以通过使ParkingLot成为模板类来实现此目的。

template<typename T>
class ParkingLotBuilding
{
public:
    T Floor1, Floor2;
}

然后在创建ParkingLotBuilding时,您可以使用以下类型:

ParkingLotBuilding<ParkingLot>
ParkingLotBuilding<DerivedParkingLot>

此外,如果您不想一直使用模板,只想使用ParkingLotBuildingDerivedParkingLotBuilding,则可以将类重命名为Building并使用typedef:

typedef Building<ParkingLot> ParkingLotBuilding
typedef Building<DerivedParkingLot> DerivedParkingLotBuilding

这种方法并不完全是ParkingLotBuilding类型之间的继承(可能不是最好的方法 - 我之前从未见过这种方法),但它可能会做你需要的。

答案 2 :(得分:0)

正如JohnSmith指出的那样,你不能覆盖数据成员,只能覆盖成员函数。由于ParkingLotBuilding包含ParkingLot值,而不包含ParkingLot指针或引用,因此即使在DerivedParkingLot中也不能以多态方式使用它们。 (这就是C ++的工作原理:只有指针和引用可以有动态类型。)

这意味着如果您无法更改ParkingLotBuilding类(或CheckBuilding函数),那么您就会陷入困境。没有派生可以使CheckBuilding函数在DerivedParkingLot对象上运行。

这个故事的寓意是,课程必须从一开始就设计为继承。

答案 3 :(得分:0)

在您的示例中,Floor1无法知道它是否在ParkingLotBuilding或DerivedParkingLotBuilding中实例化。

您可以使用RTTI来处理以下内容:

CheckBuilding (ParkingLotBuilding *building)
{
    if (dynamic_cast<DerivedParkingLogBuilding*>(building))
    {
        // Floor is in a derived parking log building
    }
    else
    {
        // Floor is in a parking lot building
    }
}

如上所述,尽管如此,这并不是最好的。