我需要使用 C++。 C++11 会很有趣,但我宁愿没有。我有以下类结构。
class Wheel { /*...*/ };
class MtbWheel : public Wheel { /*...*/ };
class Bike { Wheel front_wheel; };
class Mountainbike : public Bike { MtbWheel front_wheel; };
现在,这完全有效:Mountainbike 覆盖了 front_wheel,因此可以使用 MtbWheel。不过,就软件技术而言,我并不高兴。
- 我更喜欢不允许覆盖 front_wheel,或者至少限制由不继承类 Wheel 的类进行覆盖。
- 我不想覆盖 front_wheel,我只想向它“添加”属性。
编辑:是否有没有虚函数但使用模板的解决方案?
最佳答案
你的 front_wheel
成员Mountainbike
类不会 覆盖 front_wheel
,它隐藏它。 Mountainbike
类实际上有两个 front_wheel
成员,但来自 Bike
的那个类被 Mountainbike
中声明的类隐藏.意思是如果 Bike
访问 front_wheel
, 它将访问 Wheel
类型的对象,而当 Mountainbike
访问 front_wheel
, 它将访问 MtbWheel
类型的对象- 但是这两个轮子对象彼此不认识!
更好的 OO 设计应该是 front_wheel
例如Bike
中的指针(或者更好的智能指针),并在 Mountainbike
的构造函数中初始化它持有派生自 Wheel
的类的对象最适合 Mountainbike
.这样,当访问 front_wheel 时,一种方式或其他虚拟功能当然会发挥作用。
根据 Steve Jessop 在下面评论中的建议,另一种解决方案是使用模板而不是使用多态性:
class Wheel { /*...*/ };
class MtbWheel : public Wheel { /*...*/ };
template <typename WheelType>
class Bike { WheelType front_wheel; };
class Mountainbike : public Bike<MtbWheel> { /* ... */ };
这样,在 front_wheel 上操作时就不会涉及虚函数。但是,对于这样的解决方案,有一些要点需要考虑:
- 对于您使用 Bike 的每个不同的 WheelType,将创建单独的代码;如果您有许多不同的此类类型,这可能会导致代码膨胀。
- 如果您有多个派生自
Bike
的类使用不同的 WheelType 参数,它们不具有相同的基类(请参阅 Steve Jessop 的评论和第 1 点),因此也无法进行多态访问。 - 您不能在
WheelType
上实现显式接口(interface)作为模板参数传递给 Bike;只有隐式接口(interface)由Bike
中使用的方法和成员定义.不过这应该没问题,因为编译器仍然可以验证该隐式接口(interface)。
关于c++ - 继承时避免覆盖成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12387324/