c++ - 继承时避免覆盖成员

标签 c++ inheritance overriding

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

相关文章:

java - 限制子类中的函数调用

c++ - 如何为特定类(如STL容器)的成员函数或变量创建别名

java - 另一个 "cannot find symbol"

c++ - 大型计算后减少 C++ 程序的堆大小

c++ - 可选共享库

c++ - 文件关闭后如何避免数组中的对象超出范围?

c++ - 编写一个 Lambda 函数,将 'remembers' 值传递给它

javascript - 为什么我不能 "overwrite"javascript 中的方法?

java - 实现接口(interface)方法时不允许@Override

iOS 如何覆盖 NavigatonController 的 pop 和 push 方法?