Private virt function can be called with Base class ptr

Discussion in 'C++' started by vijay, Aug 22, 2003.

  1. vijay

    vijay Guest

    Hello
    I wanted to understand a contradictory design of C++

    class A
    {public:
    virtual void f(){ cout<<" base f"<<endl; }
    };

    class B:public 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)


    Vijay
     
    vijay, Aug 22, 2003
    #1
    1. Advertisements

  2. On Fri, 22 Aug 2003 11:49:27 +0530, "vijay" <> wrote:

    >Hello
    >I wanted to understand a contradictory design of C++
    >
    >class A
    >{public:
    > virtual void f(){ cout<<" base f"<<endl; }
    >};
    >
    >class B:public A
    >{
    >private:
    > void f(){ cout<<"private derived B f"<<endl;};
    > };
    >main()


    Just a note: the standard requires 'main' to have return type 'int'.


    >{
    > 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)


    That's no big mystery. The compiler uses the statically available type,
    namely A. It cannot check at compile time the dynamic type of *p (well,
    it can in this particular case, but not in general).

    More difficult: why does C++ allow you to change a method from 'public'
    to 'private' in a derived class?

    Well, it can be useful in some cases. Determining in which cases it's
    more confusing than useful would be hard, if not practically impossible.
    And so C++ allows it, because 'the programmer knows best'; some other
    languages disallow it, because 'the compiler knows best'.
     
    Alf P. Steinbach, Aug 22, 2003
    #2
    1. Advertisements

  3. vijay

    Attila Feher Guest

    vijay wrote:
    > Hello
    > I wanted to understand a contradictory design of C++
    >
    > class A
    > {public:
    > virtual void f(){ cout<<" base f"<<endl; }
    > };
    >
    > class B:public 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. :) )


    --
    Attila aka WW
     
    Attila Feher, Aug 22, 2003
    #3
  4. vijay

    Param Guest

    Hi
    The simple principle followed by C++ in accessing virtual functions is
    as follows...
    1. Availability .
    Whether the function u are calling is available... In this case it is
    available in the class A
    2. Accessibility :
    Whether the function u are calling is accessible .. It is accessible
    in Class A which is public
    3. Virtiual :
    Whether the function is virtual . . It is in this case... The compiler
    will built a vtable and store the address of function of the derived class
    function.
    As far as the access check is concerned it is done at compile time only ..
    So it passes through and u can bypass the private access of the derived
    class. The pointer u are using is still the base class pointer.
    If u try the reverse way i mean u make base class function private and
    derived class function public the compilation wont go through because the
    compiler will fail in the second step..

    So this is the reason why it is possible.

    Param
    Siemens Information Systems Ltd


    "Attila Feher" <> wrote in message
    news:bi4f2b$rg0$...
    > vijay wrote:
    > > Hello
    > > I wanted to understand a contradictory design of C++
    > >
    > > class A
    > > {public:
    > > virtual void f(){ cout<<" base f"<<endl; }
    > > };
    > >
    > > class B:public 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. :) )
    >
    >
    > --
    > Attila aka WW
    >
    >
     
    Param, Aug 22, 2003
    #4
  5. vijay

    Attila Feher Guest

    Param wrote:
    > Hi
    > The simple principle followed by C++ in accessing virtual
    > functions is as follows...

    [SNIP]

    a.) Why do you post this as a reply to me?

    b.) Why do you top-post?
    http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4

    BTW the OP did not ask for what - mechanism make this work in this way -
    but - why is this nonsense allowed (if you let me exaggerate). At least
    that was my understanding.

    --
    Attila aka WW
     
    Attila Feher, Aug 22, 2003
    #5
  6. "vijay" <> wrote in message news:<bi4c7q$73g$>...

    > class A
    > {public:
    > virtual void f(){ cout<<" base f"<<endl; }
    > };
    >
    > class B:public 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)


    All the compiler is allowed to consider when compiling p->f() is that
    p is a pointer to A and A::f is public. Access specifiers are a
    compile-time feature and are not checked when dispatching virtual
    function calls at run-time.

    More importantly: Never attempt to hide a function inherited from a
    public base class. Users can always access any public function in a
    public base class through a pointer or reference to that class, even
    if it refers to a derived class where that function is hidden. If you
    can't support the entirety of the base class interface, don't inherit
    it -- at least, not publicly:

    class Base {
    public: void f ();
    void g ();
    };

    // private inheritance and using declarations
    class PrivateInheritance : private Base {
    public: using Base::f; // make Base::f accessible
    };

    // composition and proxy methods
    class Composition {
    public: void f () { myBase.f(); } // make Base::f accessible
    private: Base myBase;
    };

    See also this thread:

    <http://groups.google.com/groups?th=9aacc58aeaa1bc4>

    - Shane
     
    Shane Beasley, Aug 22, 2003
    #6
  7. vijay

    vijay Guest

    Thanks param,But I know this,
    u can look at my question that why does c++ design allowed this !!!!
    vijay

    "Param" <> wrote in message
    news:bi4qd3$4i2$...
    > Hi
    > The simple principle followed by C++ in accessing virtual functions is
    > as follows...
    > 1. Availability .
    > Whether the function u are calling is available... In this case it

    is
    > available in the class A
    > 2. Accessibility :
    > Whether the function u are calling is accessible .. It is

    accessible
    > in Class A which is public
    > 3. Virtiual :
    > Whether the function is virtual . . It is in this case... The

    compiler
    > will built a vtable and store the address of function of the derived class
    > function.
    > As far as the access check is concerned it is done at compile time only ..
    > So it passes through and u can bypass the private access of the derived
    > class. The pointer u are using is still the base class pointer.
    > If u try the reverse way i mean u make base class function private and
    > derived class function public the compilation wont go through because the
    > compiler will fail in the second step..
    >
    > So this is the reason why it is possible.
    >
    > Param
    > Siemens Information Systems Ltd
    >
    >
    > "Attila Feher" <> wrote in message
    > news:bi4f2b$rg0$...
    > > vijay wrote:
    > > > Hello
    > > > I wanted to understand a contradictory design of C++
    > > >
    > > > class A
    > > > {public:
    > > > virtual void f(){ cout<<" base f"<<endl; }
    > > > };
    > > >
    > > > class B:public 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. :) )
    > >
    > >
    > > --
    > > Attila aka WW
    > >
    > >

    >
    >
     
    vijay, Aug 22, 2003
    #7
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alf P. Steinbach
    Replies:
    6
    Views:
    649
    John Carson
    Sep 3, 2005
  2. Replies:
    2
    Views:
    945
    Noah Roberts
    Jun 9, 2006
  3. Inconnu
    Replies:
    0
    Views:
    245
    Inconnu
    Jun 22, 2011
  4. Inconnu
    Replies:
    4
    Views:
    388
    Johannes Schaub (litb)
    Jun 23, 2011
  5. DSF
    Replies:
    7
    Views:
    245
    James Kuyper
    Jun 12, 2014
Loading...

Share This Page