派生之一未使用纯虚函数 类

Pure virtual function not used in one of the derived classes

我之前也问过类似的问题,但是因为想不出具体的例子,所以删掉了。我现在想出了一个。我经常发现自己在设计代码时,虚函数只对部分子classes 有用,但不是全部。

这里是 drivingflying 继承的基础 class travel 的示例。 travel 有一个计算速度和高度的 compute_travel_info() 函数。前者与驾驶和飞行相关,而后者仅与飞行相关。

在这个设计中,driving::compute_altitude() 什么都不做,但我们必须定义它,因为该函数是纯虚函数(我也可以在 travel 中将其设为虚函数并定义它,然后不在 driving 中覆盖它)。另外,理想情况下,如果 compute_travel_info 中的 compute_altitude() 函数在 driving 对象上运行,我什至不想调用它,因此代码看起来可能会产生误导书面。

我所做的被认为是不好的做法吗?有一个subclasses中没有用的虚函数,而调用一些subclasses中没有用到的虚函数,是不是让人皱眉头?

请注意,这只是一个特定示例,理想情况下,我想要一个普遍适用的答案,而不仅仅是提供的特定示例。换句话说,我不希望读者过于关注这个例子

class travel
{
  public:
       //function for representing the state in bits
   void compute_travel_info()
   {
      compute_velocity();

      compute_altitude();
   }

  private:
    double velocity;
    virtual void compute_velocity() = 0;
    virtual void compute_altitude() = 0;
};

class flying : domain
{
  void compute_velocity()
  {
    //compute the velocity
  }
  void compute_altitude()
  {
    //compute the altitude
  }    
};

class driving : travel
{
  void compute_velocity()
  {
    //compute the velocity
  }
  void compute_altitude()
  {
    //do nothing (assume car is driving on a flat earth where altitude doesn't change)
  } 
};

显然 compute_altitude 不应该是您的虚拟接口的一部分,因为如果它在派生 class 中作为存根实现,则不能保证通过基指针调用它会做任何合理的事情。

但是,compute_travel_info 似乎确实是虚拟接口的一部分,它应该始终可以通过基指针调用。

因此 compute_travel_info 应该是(纯粹的)virtual 并在所有派生的 class 中实现。其中一些派生的 classes 可能有一个被调用的 compute_altitude 函数,有些可能没有,但这对基础 class 应该无关紧要。基础 class 根本不应该有 compute_altitude 函数。

您可以在基础 class 中为 compute_travel_info 提供一个默认实现,它仅在需要时被覆盖。

您还可以在派生 class 中使用限定名称(例如 this->travel::compute_travel_info())调用 compute_travel_info 的基础 class 实现,如果您只需要添加一些额外的工作。

或者您可以将常见行为移动到另一个基础 class 函数中,该函数由派生的 classes 中的 compute_travel_info 实现调用。

您可以在飞行中添加 compute_travel_info 函数的覆盖。

在这个重新定义的函数中,您可以回调父 class 的函数,该函数只包含 compute_velocity 函数,然后仅在重写函数中调用 compute_altitude 函数.