C++派生类用另一个派生类覆盖基类的成员?
Posted
技术标签:
【中文标题】C++派生类用另一个派生类覆盖基类的成员?【英文标题】:C++ Derived class overriding member of base class with another derived class? 【发布时间】:2013-08-22 21:32:04 【问题描述】:我有这样的课程:
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?那可能吗?抱歉,如果我没有正确解释这个问题,我不知道如何询问这个问题。谢谢
【问题讨论】:
你不能覆盖成员,只能覆盖方法 补充一下 JohnSmith 所说的:由于ParkingLotBuilding
包含 ParkingLot
值,而不是 ParkingLot
指针或引用,因此它们不能多态使用,即使在 DerivedParkingLot
中也是如此。
@zindorsky 我认为这是正确的答案。如果您或 John 想将其作为答案提交并进行解释,我会将其标记为正确。
【参考方案1】:
正如 JohnSmith 所指出的,您不能覆盖数据成员,只能覆盖成员函数。由于ParkingLotBuilding
包含ParkingLot
值,而不是ParkingLot
指针或引用,因此它们不能多态使用,即使在DerivedParkingLot
中也是如此。 (这正是 C++ 的工作原理:只有指针和引用才能具有动态类型。)
这意味着如果您无法更改 ParkingLotBuilding
类(或 CheckBuilding
函数),那么您将陷入困境。没有任何推导可以让CheckBuilding
函数对DerivedParkingLot
对象进行操作。
这个故事的寓意是,必须从一开始就为继承设计类。
【讨论】:
【参考方案2】:实际上你只是从一个 ParkingLot 实例调用 DerivedParkingLot 函数?
您的代码已经通过将 something 方法指定为虚拟方法来做到这一点,它会自动搜索其继承树中最低的方法。
一个简单的测试方法是在ParkingLot和DerivedParkingLot中实现something方法,在每个中放入不同的消息并检查它
【讨论】:
【参考方案3】:您可能能够解决此问题的一种方法是将ParkingLot
设为模板类。
template<typename T>
class ParkingLotBuilding
public:
T Floor1, Floor2;
那么在创建ParkingLotBuilding
时,您可以使用这些类型:
ParkingLotBuilding<ParkingLot>
ParkingLotBuilding<DerivedParkingLot>
另外,如果您不喜欢一直使用模板并且只想使用 ParkingLotBuilding
和 DerivedParkingLotBuilding
,您可以将类重命名为 Building
并使用 typedefs:
typedef Building<ParkingLot> ParkingLotBuilding
typedef Building<DerivedParkingLot> DerivedParkingLotBuilding
这种方法并不完全是 ParkingLotBuilding
类型之间的继承(并且可能不是最好的方法 - 我以前从未见过这种方法),但它可能会满足您的需求。
【讨论】:
【参考方案4】:在您的示例中,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
正如上面所指出的那样,这样做并不是最好的。
【讨论】:
以上是关于C++派生类用另一个派生类覆盖基类的成员?的主要内容,如果未能解决你的问题,请参考以下文章