The method fun()
in the Derived class is private. When we call the function ptr->fun()
through run time polymorphism, it is executing.
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 anyone please explain what is happening?
First of all, your Derived::fun()
is also virtual
, because if a function in a derived class has the same declaration as a virtual function in the base class, the function in derived class automatically gets virtual
, even if that was not explicitly specified.
Secondly, it is completely OK to access private virtual functions via public intermediate functions from the base class, see, for example, this answer and its links, particularly Virtuality by Herb Sutter. A sample code might be 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, is a similar situation: the main
is allowed to access ptr->fun()
, but due to virtuality this fun()
happens to be Derived::fun()
.
UPD: expanding on a comment
But doesn't this sound a little alarming.. I mean, all the functions that derive from the Base class, will have their private members accessible to the friend functions of the Base class
No, not all the functions of Derived
will be accessible to the friends of Base
, but only those that can be accessible via Base
pointer. For example:
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 accessed from 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 virtual
function are intentionally extensible, and any override of virtual
function in Derived
means that that function can be called via Base
pointer; this is the main purpose of virtual
functions. If Derived
makes its overriding function private
, it still should be conscious that the function can be accessed via Base
pointer, because that is the main idea behind the virtual
functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With