gpt4 book ai didi

c++ - 两个相关的类层次结构——覆盖虚函数

转载 作者:行者123 更新时间:2023-11-30 02:57:15 26 4
gpt4 key购买 nike

假设我有这个基类:

struct Vehicle {
//"op" stands for the operator of the vehicle
//examples: pilot, truck driver, etc.
virtual void insert_op(Op op) = 0;
//other members...
};

还有这两个子类

struct Truck : public Vehicle {
void insert_op(Op op) override {
//prepare Truck with truck driver
}
};

struct Airplaine : public Vehicle {
void insert_op(Op op) override {
//prepare Airplaine with pilot
}
};

如您所料,这是另一个层次结构:

struct Op {};
struct TruckDriver : public Op {};
struct Pilot : public Op {};

您已经看到问题了,不是吗?我想强制卡车只接受卡车司机和强制飞机只接受飞行员,但这在当前设计中是不可能的。 C++ 不允许为重写的虚函数使用 diff 参数。

我想我可以在 insert_op 的每个子类实现中对“Op”的类型进行运行时类型检查,但这听起来是一个非常丑陋的解决方案,而且它在编译时不强制执行。

有什么出路吗?

最佳答案

你的 Vehiclevirtual void insert_op(Op op) 这意味着“每辆车都可以接受任何 Op”。

因此,根据您的设计,Truck 不是 Vehicle 子类的有效候选者,因为它不能接受任何 Op - 它只能接受 TruckDriver

相关:Liskov substitution principle


问题出在你的设计上,而不是在实现上。我建议简化您的类层次结构。真的需要那么多类和继承吗?您可以简单地使用具有标识其类型的字段的 VehicleOp 吗?


让我进一步解释设计问题:

假设一些对象 A 有一个方法 manVehicle(Vehicle&)Truck 是 Vehicle 的子类,因此可以使用 Truck 类型的对象调用此方法。

但是,A 的实现不知道Vehicle 的具体类型。它只知道所有车辆都有一个方法 insert_op(Op),因此它尝试调用 insert_op(Pilot()) 是有效的,即使车辆实际上是卡车

结论:

  • 甚至不可能进行编译时检查

  • 运行时检查可以工作...

    • 但只会掩盖问题。 Vehicle 的用户希望能够在任何 Vehicle 上调用 insert_op(Op)

一个解决方案是将 Vehicle 接口(interface)修改为:

struct Vehicle {
virtual bool can_insert_op(Op op) = 0;
virtual void insert_op(Op op) = 0;
};

并对其进行记录,以便调用者知道 insert_op 只能使用满足 can_insert_opOp 在给定的 上调用>车辆。或者类似的东西(比如 insert_op 中记录的异常“此车辆的无效 op 类型”)- 只要它是此接口(interface)的记录部分,任何东西都可以工作。


顺便说一下技术说明:您可能希望这些方法通过指针或引用获取 Op 而不是复制它,以避免不必要的复制以及 slicing .

关于c++ - 两个相关的类层次结构——覆盖虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14787385/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com