我需要使用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/

10-11 14:56