私人纯虚函数的要点是什么? [英] What is the point of a private pure virtual function?

查看:137
本文介绍了私人纯虚函数的要点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

推荐答案

p>主题中的问题表明了一个很常见的混乱。混乱是很常见的, C ++常见问题解答主张不使用私人虚拟,很长一段时间,因为混乱似乎一个坏东西。

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*/}
    virtual void SetState( int var, int val )  {/*some implementation*/}
};

现在让我们假设你想创建一个派生类,你需要提供一个新的实现方法,它以两个int作为参数。

Now let's assume you want to create a derived class and you need to provide a new implementation only for the method, that takes two ints as arguments.

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声明(或重新定义第二个重载)您可以在下面的情况下遇到麻烦。

If you forgot to put the using declaration in the derived class (or to redefine the second overload), you could get in trouble in the scenario below.

MyTurbochargedV8* myV8 = new MyTurbochargedV8();
myV8->SetState(5, true);

如果您没有阻止隐藏 Engine 成员,语句:

If you didn't prevent the hiding of the Engine members, the statement:

myV8->SetState(5, true);

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

would call void SetState( int var, int val ) from the derived class, converting true to int.

如果接口不是虚拟的,并且虚拟实现是非公开的,就像在你的例子中,派生类的作者有一个问题要考虑,可以写成

If the interface is not virtual and the virtual implementation is non-public, like in your exmaple, the author of the derived class has one less problem to think about and can simply write

class MyTurbochargedV8 : public Engine
{
private:
    void SetStateInt(int var, int val )  {/*new implementation*/}
};

这篇关于私人纯虚函数的要点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆