First of all, your Derived::fun() also virtual , because if the function in the derived class has the same declaration as the virtual function in the base class, the function in the derived class automatically gets virtual , even if it is not explicitly specified.
Secondly, it is quite normal to access private virtual functions through public intermediate functions from the base class, see, for example, this answer and its links, in particular Virtuality by Herb Sutter . Sample code might look like
#include<iostream> using namespace std; class Derived; class Base { private: virtual void fun() { cout << "Base Fun"; } public: void funInt() { fun(); } }; class Derived: public Base { private: virtual void fun() { cout << "Derived Fun"; } }; int main() { Base *ptr = new Derived; ptr->funInt(); return 0; }
So what happens in your case, I think this is a similar situation: main has access to ptr->fun() , but due to virtuality this fun() happens to be Derived::fun() .
UPD : comment extension
But that doesn't sound a bit alarming. I mean that all functions that come from the base class will have their private members available for functions of a friend of the Base class
No, not all Derived functions will be available to Base friends, but only those that can be accessed using the Base pointer. For instance:
class Base { virtual void fun(); friend int main(); } class Derived: public Base { virtual void fun(); virtual void foo(); void bar(); }
only Derived::fun() can be obtained from the main:
int main() { Derived *ptr = new Derived; Base* baseptr = ptr; baseptr->fun(); // ok, calls Derived::fun() baseptr->foo(); // error, no such function in Base ptr->foo(); // error, foo is private return 0; }
Note that the virtual function is intentionally extensible, and any redefinition of the virtual function in Derived means that this function can be called using the Base pointer; this is the main goal of virtual functions. If Derived makes its overriding function private , you should still be aware that you can access this function with the Base pointer, because this is the basic idea of virtual functions.