我需要使用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),因此也无法进行多态访问。您不能在作为模板参数传递给Bike的
WheelType
上强制使用显式接口;仅隐式接口由Bike
中使用的方法和成员定义。但是,那应该没问题,因为编译器仍然可以验证该隐式接口。关于c++ - 继承时避免覆盖成员,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12387324/