CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Feb 2009
    Posts
    326

    access specifier of base virtual function

    Hi,

    A is the base class
    B is the derived from class A

    A has a public virtual function f1()
    B has a private virtual function f1()

    B::f1() not accessible using an object of class B however it is accessible through A* (base pointer)

    Questions:
    1) Is this because determining the access specifiers (public, protected, private) are checked by the compiler at compile time and which virtual function is to be invoked is decided runtime ?
    2) Is this a bug ? (I am using gcc 4.2.1)

    Pasted below is the code:
    Code:
    #include <iostream>
    
    class A
    {
        public:
            virtual void f1() { std :: cout << "A::f1()\n"; }
    };
    
    class B : public A
    {
        private:
            virtual void f1() { std :: cout << "B::f1()\n"; }
    };
    
    int main()
    {
        A a1;
        B b1;
    
        a1.f1();
        //b1.f1(); //Can't access through the object - As expected, this line throws compilation error
    
        //Accessing f1() through base pointer
        A* aPtr = &b1;
        aPtr -> f1(); //Able to access B::f1() though B::f1() is private
    
        return(0);
    }
    Last edited by Muthuveerappan; July 9th, 2011 at 08:08 AM. Reason: explaining the question

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: access specifier of base virtual function

    Quote Originally Posted by uthuveerappan
    2) Is this a bug ?
    It is probably a bug in your class design because, in a way, this violates the Liskov substitution rule.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Feb 2009
    Posts
    326

    Re: access specifier of base virtual function

    Thanks Laserlight, I agree that the design doesn't follow the Liskov substitution principle.

    However my question is:
    B::f1() is private and shouldn't be accessible outside the class B, however i am able to access B::f1() outside the class B (using base pointer). Why / how is this possible ?

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: access specifier of base virtual function

    Quote Originally Posted by Muthuveerappan
    B::f1() is private and shouldn't be accessible outside the class B, however i am able to access B::f1() outside the class B (using base pointer). Why / how is this possible ?
    I guess that the answer to "why" is that the derived class author is expected to know better, hence there is no need to make the compiler check that the access control is not tightened when overriding. The "how" is simply a matter of not checking the access control when overriding, and since the check of the call through the base class pointer passes, what you observed becomes possible.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    May 2009
    Posts
    2,413

    Re: access specifier of base virtual function

    Quote Originally Posted by Muthuveerappan View Post
    Thanks Laserlight, I agree that the design doesn't follow the Liskov substitution principle.
    Following the LSP is important only if B is intended as a subtype of A. But it could also be that the sole purpose of B is to provide an implementation of A.

    I use this a lot. Typically the base class A is a pure virtual interface. It has several derived implementations B, C, D, etcetera but these always appear polymorphically as A objects only. To express this in the design it's nice to be able to declare all A methods private in the derived classes. This prevents unintentional use of the derived classes as A subtypes.

    However my question is:
    B::f1() is private and shouldn't be accessible outside the class B, however i am able to access B::f1() outside the class B (using base pointer). Why / how is this possible ?
    In my view it's because the access specifiers are concerned with type, not implementation. This is what matters from a type perspective.

    void f1();

    In A f1() is public and in B it's private and that will always be upheld. The fact that B:f1() effectively is getting called when A:f1() is called is an implementation detail.

  6. #6
    Join Date
    Feb 2009
    Posts
    326

    Re: access specifier of base virtual function

    Thanks Nuzzle and Laserlight

    Just to summarize the reason how this happened:
    1) Access is checked by the compiler at compile time, the fact that it is A::f1() public allows the compiler to let it pass through
    2) Which virtual function would be invoked is determined at runtime based on the table, and at runtime access checks are not performed again.

    I suppose that is how it is possible to access B::f1() outside the class through the base pointer.

    I agree that LSP need not be followed always, it depends what the objective of the program.

    Given below shows a scenario when this could come handy:
    ====================================

    Aim - To build a function display() in the base class and it must invoke the corresponding version of f1() ( A::f1() or B::f1() ) depending on the calling object of the function display(). Also A::f1() and B::f1() should not be accessible outside of the class A and class B.

    Explanation:
    ========
    - A::f1() and B::f1() are both private virtual functions
    - A:isplay() is a public non-virtual function and invokes f1()

    - Depending on what the calling object is (or what the pointer points to), corresponding f1() gets invoked.
    - At the same time A::f1() and B::f1() are both private not allowing to be accessed outside of the class A and class B

    Reason:
    =====
    - This would be possible because "this" pointer of class A would be of the type const A* const


    Code:
    #include <iostream>
    
    class A
    {
        public:        void display() const { f1(); } //This can call A::f1() or B::f1() depending on the calling object
        
        private:
            virtual void f1() const { std :: cout << "A::f1()\n"; }
    };
    
    class B : public A
    {
        private:
            virtual void f1() const { std :: cout << "B::f1()\n"; }
    };
    
    int main()
    {
        B b1; 
            
        //Accessing f1() through base pointer
        A* aPtr = &b1;
        aPtr -> display(); //Depending on what aPtr points, corresponding
    
        return(0);
    }
    Last edited by Muthuveerappan; July 10th, 2011 at 05:39 AM. Reason: editing to improve readability

  7. #7
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: access specifier of base virtual function

    Your new example demonstrates the non-virtual interface idiom, so it is a slightly different ball game from the scenario that nuzzle presented. In fact, it conforms to Liskov substitution.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  8. #8
    Join Date
    Feb 2009
    Posts
    326

    Re: access specifier of base virtual function

    Laserlight - Yes you are correct, my 2nd example follows LSP.

    I found it interesting that B::f1() could be accessed outside of class B. In this case class A:isplay() (base class function) access's the B::f1() (derived class's function) though B::f1() is private.

  9. #9
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: access specifier of base virtual function

    Quote Originally Posted by Muthuveerappan
    In this case class A:isplay() (base class function) access's the B::f1() (derived class's function) though B::f1() is private.
    Not exactly. A:isplay is inherited, so you could say that it is the B object's own display function that is accessing a private member function, so that is fine. Consider the error that you would get if you tried:
    Code:
    void A::display() const
    {
        B b;
        b.f1();
    }
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  10. #10
    Join Date
    Feb 2009
    Posts
    326

    Re: access specifier of base virtual function

    As per my understanding (correct me if i am wrong):

    1) Yes B inherits A, but display() is a function that belongs to A and is only inherited by B.

    It was possible for A:isplay() to invoke B::f1() because of the following reasons:
    a) The "this" pointer of class A is of the type "const A* const" and was pointing to an object of B
    b) It wouldn't have been possible if A::f1() and B::f1() weren't virtual functions

    2) b.f1() is definitely not possible because that is the objective of the program and B::f1() is private

  11. #11
    Join Date
    May 2009
    Posts
    2,413

    Re: access specifier of base virtual function

    Quote Originally Posted by Muthuveerappan View Post
    Just to summarize the reason how this happened:
    1) Access is checked by the compiler at compile time, the fact that it is A::f1() public allows the compiler to let it pass through
    2) Which virtual function would be invoked is determined at runtime based on the table, and at runtime access checks are not performed again.

    I suppose that is how it is possible to access B::f1() outside the class through the base pointer.
    That's the wrong way to look at it. Trying to understand C++ by secondguessing the compiler or runtime system is close to meaningless.

    C++ should be understood by its definition. Of course the C++ designers must make sure there exists a reasonably efficient realization for each language feature they put in. This is even a C++ design goal but it doesn't explain why the language feature is there in the first place.

  12. #12
    Join Date
    Feb 2009
    Posts
    326

    Re: access specifier of base virtual function

    Thanks Nuzzle, I suppose it is better to treat it as a feature of C++ since i am not fully aware of what goes behind the scene.

  13. #13
    Join Date
    Oct 2008
    Posts
    1,456

    Re: access specifier of base virtual function

    Quote Originally Posted by Muthuveerappan View Post
    Thanks Nuzzle, I suppose it is better to treat it as a feature of C++ since i am not fully aware of what goes behind the scene.
    actually, there's not much happening "behind the scene" in this case; the C++ designers simply choosed to maintain access rules and polymorphic behavior rules as much orthogonal as possible. Once you have been granted access to a member ( a method, a variable, a type, a special member such as a constructor etc... ) then the rules involving the invocation of virtual functions apply indipendently of the specific way you accessed it.

  14. #14
    Join Date
    Feb 2009
    Posts
    326

    Re: access specifier of base virtual function

    Thanks superbonzo for clarifying that

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured