我在头文件中遇到以下代码:

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类或从其派生的类必须为这些纯虚函数提供实现。但是我不认为派生类可以访问这些私有(private)函数来重新实现它们-那么为什么要将它们虚拟化?

最佳答案

主题中的问题表明了一个非常普遍的困惑。 C++ FAQ长期以来一直提倡不使用私有(private)虚拟机,这是很常见的困惑,因为困惑似乎是一件坏事。

因此,首先要消除困惑:是的,可以在派生类中重写私有(private)虚拟函数。派生类的方法不能从基类调用虚函数,但是它们可以为其提供自己的实现。根据Herb Sutter的说法,在基类中具有公共(public)非虚拟接口(interface),并可以在派生类中自定义私有(private)实现,可以更好地“将接口(interface)的规范与实现的可自定义行为的规范分开”。您可以在他的文章"Virtuality"中了解更多信息。

但是,在我看来,您提供的代码中还有一件有趣的事情,值得更多注意。公用接口(interface)由一组重载的非虚函数组成,这些函数称为非公用,非重载的虚函数。像在C++世界中一样,它是一个习惯用法,它有一个名称,当然它是有用的。名字是(惊喜,惊喜!)

“公共(public)重载非虚拟 call 保护的非重载虚拟”

它有助于properly manage the hiding rule。您可以阅读有关它的更多信息here,但我将尽力对其进行解释。

想象一下,Engine类的虚函数也是其接口(interface),并且它是一组重载函数,它们不是纯虚函数。如果它们是纯虚拟的,则仍然会遇到相同的问题,如下所述,但在类层次结构中较低。

class Engine
{
public:
    virtual void SetState( int var, bool val ) {/*some implementation*/}
    virtual void SetState( int var, int val )  {/*some implementation*/}
};

现在,假设您要创建一个派生类,并且只需要为该方法提供一个新的实现,该方法需要两个int作为参数。
class MyTurbochargedV8 : public Engine
{
public:
    // To prevent SetState( int var, bool val ) from the base class,
    // from being hidden by the new implementation of the other overload (below),
    // you have to put using declaration in the derived class
    using Engine::SetState;

    void SetState( int var, int val )  {/*new implementation*/}
};

如果忘记将using声明放在派生类中(或重新定义第二个重载),则在以下情况下可能会遇到麻烦。
MyTurbochargedV8* myV8 = new MyTurbochargedV8();
myV8->SetState(5, true);

如果您没有阻止Engine成员的隐藏,则声明:
myV8->SetState(5, true);

会从派生类调用void SetState( int var, int val ),将true转换为int

如果接口(interface)不是虚拟的,并且虚拟实现是非公共(public)的(例如在您的示例中),则派生类的作者要考虑的问题少了一点,可以简单地编写
class MyTurbochargedV8 : public Engine
{
private:
    void SetStateInt(int var, int val )  {/*new implementation*/}
};

关于c++ - 私有(private)纯虚函数的意义是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3970279/

10-11 22:37
查看更多