我在头文件中发现了以下代码:
I came across the following code in a header file:
class Engine
{
public:
void SetState( int var, bool val );
{ SetStateBool( int var, bool val ); }
void SetState( int var, int val );
{ SetStateInt( int var, int val ); }
private:
virtual void SetStateBool(int var, bool val ) = 0;
virtual void SetStateInt(int var, int val ) = 0;
};
对我来说,这意味着 Engine
类或从它派生的类必须为那些纯虚函数提供实现.但我不认为派生类可以访问这些私有函数来重新实现它们——那么为什么要让它们成为虚拟的呢?
To me, this implies that either the Engine
class or a class derived from it, has to provide the implementation for those pure virtual functions. But I didn't think derived classes could have access to those private functions in order to reimplement them - so why make them virtual?
该主题中的问题暗示了一个非常常见的混淆.这种混淆很常见,C++ FAQ 长期以来一直反对使用私有虚拟机,因为混淆似乎是坏事.
The question in the topic suggest a pretty common confusion. The confusion is common enough, that C++ FAQ advocated against using private virtuals, for a long time, because confusion seemed to be a bad thing.
所以首先要摆脱混乱:是的,可以在派生类中覆盖私有虚拟函数.派生类的方法不能从基类调用虚函数,但可以为它们提供自己的实现.根据 Herb Sutter 的说法,在基类中具有公共非虚拟接口和可以在派生类中自定义的私有实现,可以更好地将接口规范与实现的可定制行为规范分离".您可以在他的文章虚拟化"中阅读更多相关信息.
So to get rid of the confusion first: Yes, private virtual functions can be overridden in the derived classes. Methods of derived classes can't call virtual functions from the base class, but they can provide their own implementation for them. According to Herb Sutter, having public non-virtual interface in the base class and a private implementation that can be customized in the derived classes, allows for better "separation of the specification of interface from the specification of the implementation's customizable behavior". You can read more about it in his article "Virtuality".
然而,在我看来,您提供的代码中还有一件更有趣的事情,值得更多关注.公共接口由一组重载的非虚函数组成,这些函数调用非公共、非重载的虚函数.在 C++ 世界中,它是一个惯用语,它有一个名字,当然它很有用.名字是(惊喜,惊喜!)
There is however one more interesting thing in the code you presented, that deserves some more attention, in my opinion. The public interface consists of a set of overloaded non-virtual functions and those functions call non-public, non-overloaded virtual functions. As usual in the C++ world it is an idiom, it has a name and of course it is useful. The name is (surprise, surprise!)
公共重载非虚拟调用受保护的非重载虚拟"
"Public Overloaded Non-Virtuals Call Protected Non-Overloaded Virtuals"
有助于正确管理隐藏规则.您可以在此处阅读更多相关信息,但我会尝试简单解释一下.
It helps to properly manage the hiding rule. You can read more about it here, but I'll try to explain it shortly.
想象一下,Engine
类的虚函数也是它的接口,它是一组非纯虚的重载函数.如果它们是纯虚拟的,仍然会遇到同样的问题,如下所述,但在类层次结构中较低.
Imagine, that virtual functions of the Engine
class are also its interface and it is a set of overloaded functions that is not pure virtual. If they were pure virtual, one could still encounter the same problem, as described below, but lower in the class hierarchy.
class Engine
{
public:
virtual void SetState( int var, bool val ) {/*some implementation*