Why is it allowed to call derived class' private virtual method via pointer of base class?

access-specifier, c++, inheritance, virtual

Solution

Access control is performed at compile time, not runtime. There's no way in general for the call to `f()` to know the runtime type of the object pointed to by `ptr`, so there's no check on the derived class's access specifiers. That's why the call is permitted.

As for why class B is permitted to override using a private function at all - I'm not sure. Certainly B violates the interface implied by its inheritance from A, but in general the C++ language doesn't always enforce inheritance of interface, so the fact that it's Just Plain Wrong doesn't mean C++ will stop you.

So I'd guess that there's probably some use case for this class B - substitution still works with dynamic polymorphism, but statically B is not a substitute for A (e.g. there can be templates that call `f`, that would work with A as argument but not with B as argument). There may be situations where that's exactly what you want. Of course it could just be an unintended consequence of some other consideration.

Problem

``` # include <iostream> using namespace std; class A { public: virtual void f() { cout << "A::f()" << endl; } }; class B:public A { private: virtual void f() { cout << "B::f()" << endl; } }; int main() { A *ptr = new B; ptr->f(); return 0; } ``` This code works correctly and prints B::f(). I know how it works, but why is this code allowed?

Original source