Has a friend function been inherited?

The fun() method in the Derived class is private. When we call the ptr->fun() function through a run-time polymorphism, it is executed. But this violates the encapsulation property of the Derived class.

 #include<iostream> using namespace std; class Derived; class Base { private: virtual void fun() { cout << "Base Fun"; } friend int main(); }; class Derived: public Base { private: void fun() { cout << "Derived Fun"; } }; int main() { Base *ptr = new Derived; ptr->fun(); return 0; } 

Can someone explain what is happening?

+6
source share
3 answers

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.

+2
source
Functions

Friend never participate in inheritance.

What's going on here?
When a virtual method is defined in the Base class, a virtual table is created containing the address of the fun method of the Base class. And since the Derived class inherits it, VTABLE also contains the address of the Derived class fun method. Now, since main is a friend function of the Base class, the compiler allows its members access to the main method, regardless of their access specifier. Therefore, main gets the address Derived::fun and Derived class fun , which is called at run time.

+1
source

This is because you declared fun virtual. At runtime, when the vtable search is executed, it finds an entry for Derived::fun() and therefore goes to the address.

However, friend functions are not inherited, you can check this out.

 class Base { private: virtual void fun() { cout << "Base Fun"; } friend int main(); int z = 20; }; class Derived : public Base { private: void fun() { cout << "Derived Fun"; } int m = 10; }; int main() { Base *ptr = new Derived; ptr->z = 10; //Accepted ptr->m = 5; //error return 0; } 

Here the private member Derived m not available to the primary.

0
source

All Articles