派生之一未使用纯虚函数 类
Pure virtual function not used in one of the derived classes
我之前也问过类似的问题,但是因为想不出具体的例子,所以删掉了。我现在想出了一个。我经常发现自己在设计代码时,虚函数只对部分子classes 有用,但不是全部。
这里是 driving
和 flying
继承的基础 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 函数.
我之前也问过类似的问题,但是因为想不出具体的例子,所以删掉了。我现在想出了一个。我经常发现自己在设计代码时,虚函数只对部分子classes 有用,但不是全部。
这里是 driving
和 flying
继承的基础 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 函数.