C++ override private pure virtual method as public

2019-04-19 01:35发布

Why does this happen?

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();
}

Why can I override a PRIVATE virtual method as public?

5条回答
家丑人穷心不美
2楼-- · 2019-04-19 01:54

That behavior is intended. If a method is virtual then it's meant to be customizable by derived classes, regardless of access modifier.

See here

查看更多
Evening l夕情丶
3楼-- · 2019-04-19 01:59

Notice that this implementation does not change the way how the base class is accessed and a construct:

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

will not work.

I remember there is some rationale behind it described in more detail in "Effective C++" by Scott Meyers. But the key practical feature is to be able to use such flexibility in the opposite direction, to override public base class members with private functions in a derived class forcing the client to use the base class as the interface and not be tempted to use directly the derived one that should remain a hidden implementation.

查看更多
Anthone
4楼-- · 2019-04-19 02:00

If the intention is to write a private code for the base-class & to prevent the possibility of override it, implement the private function in the base class, and declare it final, otherwise: When should someone use private virtuals? ISOCPP.ORG FAQ

查看更多
别忘想泡老子
5楼-- · 2019-04-19 02:05

Why I can override PRIVATE virtual method as public???

Because you look at the base method being private at wrong angle. B::do_run being private means "only members and friends of this class can use it". To prohibit derived classes from overriding it we would need separate specifier but we can simply make it not virtual. Class A on another side allows anybody to call A::do_run() and it is up to class A designer to decide so. So there is no uplift as you see it.

查看更多
闹够了就滚
6楼-- · 2019-04-19 02:10

According to https://en.cppreference.com/w/cpp/language/virtual#In_detail overwriting a base's virtual member function only care about the function name, parameters, const/volatile-ness and ref qualifier. It doesn't care about return type, access modifier or other things you might expect it to care about.

The linked reference also specifically notes that :

Base::vf does not need to be visible (can be declared private, or inherited using private inheritance) to be overridden.

Nothing that I can find explicitly gives permission to do this, but the rules of overriding do not prevent it. It's allowed by virtue of virtual functions and function overriding existing and not disallowing this case.

If you are asking why this is how the language is, you may have to ask the standardization committee.

查看更多
登录 后发表回答