vijay said:
Hello
I wanted to understand a contradictory design of C++
class A
{public:
virtual void f(){ cout<<" base f"<<endl; }
};
class B
ublic A
{
private:
void f(){ cout<<"private derived B f"<<endl;};
};
main()
{
B b;
A* p = &b;
p->f();
}
why does the compiler allows me to call a private function in B though
accessing it directly is not possible;(B b; b.f() gives error)
Actually - I should say - it is your design, which is flawed, not C++. The
function f() is part of your public interface. C++ allows you to put it
private in the derived class (it even allows you to put it private in a base
class and then later override it and bring it public) and make it public in
the base, but that usually makes absolutely no sense to do so. In most
cases classes in a hierarchy must conform to the Liskov Substitution
Principle (
http://tinyurl.com/ktb5 [
http://www.eventhelix.com/RealtimeMantra/Object_Oriented/liskov_substitution
_principle.htm ] )
which in turn requires all derived classes to be substitutable in place of
the base. Shortly: whereever you can use a type A object, you must be able
to use a type B object as well. Now this - in turn - means that you publish
your interface in class A, and you will not change it or its meaning in any
subsequent derivations.
The wuestion (why does C++ allow it) is valid, but IMHO not so disturbing.
As Alf described it very well, C++ takes the route of not limiting the
programmers actions rather than trying to figure out what is good or wrong.
Now I do not recall any use for this scenario you have just shown to us -
but it may very well be my memory, it does not mean that there is no use for
this.
C++ has been designed at the beginning of OO. What I mean is that at that
time OO was not in widespread use, C++ was new as well etc. so the designers
of the language decided that unless they can prove that some combination of
features is absolutely useless or definitely harmful, they will allow it. I
guess this is one example of this thinking here.
Have you asked about the same "trick" the other way around, I could have
talked about the idiomatic C++ implementation of the Template Method (
http://c2.com/cgi/wiki?TemplateMethodPattern )pattern. In the template
method implementation in C++ the virtual hooks for the non-virtual template
methods are defined as private in the base class. This is done so, because
they must not be used directly, only indirectly using the template method.
In the subclasses it is not possible to call them, but it is possible to
override them - this overriding is also done as private functions. So while
in that pattern we do not change between public/private, a similarly
astonishing trick is used: we cannot call base class private virtual
function, but we can "rewrite" them in a subclass. (Of course if those
hooks might be useful in a subclass they will be declared as protected, but
then there is no trick.
)