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?
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
Notice that this implementation does not change the way how the base class is accessed and a construct:
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.
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 FAQBecause 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 notvirtual
. ClassA
on another side allows anybody to callA::do_run()
and it is up to classA
designer to decide so. So there is no uplift as you see it.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 :
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.