C ++将私有纯虚方法覆盖为public

时间:2018-06-06 14:23:06

标签: c++ oop virtual-functions private-members method-overriding

为什么会这样?

http://coliru.stacked-crooked.com/a/e1376beff0c157a1

class Base{
private:
    virtual void do_run() = 0;
public:
    void run(){
        do_run();
    }
};

class A : public Base {
public:
    // uplift ??
    virtual void do_run() override {}
};


int main()
{
    A a;
    a.do_run();
}

为什么我可以将 PRIVATE 虚拟方法覆盖为公共?

5 个答案:

答案 0 :(得分:16)

根据https://en.cppreference.com/w/cpp/language/virtual#In_detail覆盖基类的virtual成员函数,只关心函数名,参数,const / volatile-ness和ref限定符。它不关心返回类型,访问修饰符或您可能期望它关心的其他事情。

链接引用还特别指出:

  

Base :: vf不需要是可见的(可以声明为私有,或使用私有继承继承)来覆盖。

我无法明确找到的任何内容都允许这样做,但是覆盖规则并不能阻止它。凭借virtual函数和函数覆盖现有而不允许这种情况允许它。

如果你问为什么这就是语言的方式,你可能不得不问标准化委员会。

答案 1 :(得分:11)

这种行为是有意的。如果某个方法是虚拟的,则无论访问修饰符如何,它都可以通过派生类进行自定义。

请参阅here

答案 2 :(得分:2)

  

为什么我可以将PRIVATE虚方法覆盖为public ???

因为你看错了角度的私有基本方法。私有的B::do_run意味着“只有这个类的成员和朋友才能使用它”。要禁止派生类覆盖它,我们需要单独的说明符,但我们可以简单地使它不是virtual。另一方的班级A允许任何人拨打A::do_run()并由班级A设计师决定如此。所以你看到它没有隆起。

答案 3 :(得分:2)

请注意,此实现不会更改基类的访问方式和构造:

Base& b = a;
b.do_run();

不起作用。

我记得在#34; Effective C ++"中有更详细的描述背后有一些基本原理。作者:Scott Meyers。但关键的实际特性是能够在相反的方向上使用这种灵活性,在派生类中使用私有函数覆盖公共基类成员,迫使客户端使用基类作为接口,而不是试图直接使用派生的应该仍然是一个隐藏的实现。

答案 4 :(得分:0)

如果要为基类编写私有代码并防止覆盖它,请在基类中实现私有函数,并声明为final,否则:何时应使用私人虚拟机? ISOCPP.ORG FAQ

相关问题