Why can derived member function not access protected member of a baseclass object?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • blangela

    Why can derived member function not access protected member of a baseclass object?

    If I pass a base class object by reference (likely does not make a
    difference here that it is passed by reference) as a parameter to a
    derived class member function, the member function is not allowed to
    access the protected data members of the base object. This surprises
    me.

    Can someone explain why this is? I suspect there is a good reason and
    I am just having a slow day to not come up with it myself.

    Bob
  • blangela

    #2
    Re: Why can derived member function not access protected member of abase class object?

    Here is a sample program to show what I mean:

    // Base.h
    #ifndef Base_incl
    #define Base_incl

    class Derived; // forward declaration - required because Method2()
    // of the Base class references the Derived class
    class Base
    {
    public:
    Base(); // constructor

    virtual void Method1(Base &);
    virtual void Method2(Base &);
    virtual void Method3(Derived &); //it is unusual to have a
    // derived class object as a parameter for a base
    // class method, but as you see, it can be done.
    protected:
    int mBase;
    };

    #endif

    // Derived.h
    #ifndef Derived_incl
    #define Derived_incl

    #include "Base.h"

    class Derived: public Base
    {
    public:
    Derived(); // constructor

    virtual void Method2(Base &); // this method
    // overrides Base class Method2()
    virtual void Method4(Base &); // a new method
    // which is not defined for the Base class

    private:
    int mDerived;
    };

    #endif

    // Base.cpp
    #include "Base.h"
    #include "Derived.h"

    #include <iostream>
    using std::cout;
    using std::endl;

    Base::Base()
    {
    this->mBase = 2;
    }

    void Base::Method1(B ase & B_Param)
    {
    cout << (B_Param.mBase) * (this->mBase) << endl;
    }

    void Base::Method2(B ase & B_Param)
    {
    cout << this->mBase << endl;
    }

    void Base::Method3(D erived & D_Param)
    {
    Base & BRef = static_cast<Bas e &>(D_Param); // This cast creates
    // a Base class reference to the D_Param object.
    cout << BRef.mBase << endl;
    }

    //Derived.cpp
    #include "Derived.h"
    #include <iostream>
    using std::cout;
    using std::endl;

    Derived::Derive d()
    {
    this->mBase = 3;
    this->mDerived = 5;
    }

    void Derived::Method 2(Base & B_Param)
    {
    cout << this->mDerived << endl;
    }

    void Derived::Method 4(Base & B_Param)
    {
    Derived * DPtr = dynamic_cast <Derived *(&B_Param); // this cast
    // creates a Derived class pointer to B_Param, if and only if,
    // B_Param actually is Derived class object, otherwise the
    // pointer will be set to 0

    if (DPtr != 0) // if B_Param is actually a Derived class object
    cout << DPtr->mDerived << endl;
    else
    cout << B_Param.mBase << endl;
    }

    If I compile Derived.cpp I get the following errors:

    1>c:\documents and settings\blange la\desktop\poly morphismtest
    \derived.cpp(27 ) : error C2248: 'Base::mBase' : cannot access
    protected member declared in class 'Base'
    1 c:\documents and settings\blange la\desktop\poly morphismtest
    \base.h(17) : see declaration of 'Base::mBase'
    1 c:\documents and settings\blange la\desktop\poly morphismtest
    \base.h(7) : see declaration of 'Base'

    Comment

    • blangela

      #3
      Re: Why can derived member function not access protected member of abase class object?

      Sorry, it is the line:

      cout << B_Param.mBase << endl;

      in the member function below that causes the errors.

      void Derived::Method 4(Base & B_Param)
      {
      Derived * DPtr = dynamic_cast <Derived *(&B_Param); // this
      cast
      // creates a Derived class pointer to B_Param, if and
      only if,
      // B_Param actually is Derived class object, otherwise
      the
      // pointer will be set to 0

      if (DPtr != 0) // if B_Param is actually a Derived class
      object
      cout << DPtr->mDerived << endl;
      else
      cout << B_Param.mBase << endl;
      }

      Comment

      • Victor Bazarov

        #4
        Re: Why can derived member function not access protected member ofa base class object?

        blangela wrote:
        If I pass a base class object by reference (likely does not make a
        difference here that it is passed by reference) as a parameter to a
        derived class member function, the member function is not allowed to
        access the protected data members of the base object. This surprises
        me.
        >
        Can someone explain why this is? I suspect there is a good reason and
        I am just having a slow day to not come up with it myself.
        Isn't this in the FAQ? It should be.

        In short, the reason is to prevent access to members of a different type
        (across the hierarchy). If D1 and D2 derive from B, an instance of D1
        is not allowed to access any non-public members of D2 (unless they are
        friends, of course). When you pass a reference to B to a member
        function of D1, the access to members of that class is blocked because
        it *can* be a subobject of a D2 object, and not necessarily of another
        D1. Need an example? Look in the archives, we had that topic discussed
        several times over the past years.

        V
        --
        Please remove capital 'A's when replying by e-mail
        I do not respond to top-posted replies, please don't ask

        Comment

        • blangela

          #5
          Re: Why can derived member function not access protected member of abase class object?

          On Sep 25, 12:55 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
          blangela wrote:
          If I pass a base class object by reference (likely does not make a
          difference here that it is passed by reference) as a parameter to a
          derived class member function, the member function is not allowed to
          access the protected data members of the base object. This surprises
          me.
          >
          Can someone explain why this is?  I suspect there is a good reason and
          I am just having a slow day to not come up with it myself.
          >
          Isn't this in the FAQ?  It should be.
          >
          In short, the reason is to prevent access to members of a different type
          (across the hierarchy).  If D1 and D2 derive from B, an instance of D1
          is not allowed to access any non-public members of D2 (unless they are
          friends, of course).  When you pass a reference to B to a member
          function of D1, the access to members of that class is blocked because
          it *can* be a subobject of a D2 object, and not necessarily of another
          D1.  Need an example?  Look in the archives, we had that topic discussed
          several times over the past years.
          >
          V
          --
          Please remove capital 'A's when replying by e-mail
          I do not respond to top-posted replies, please don't ask
          Even with the example you supply, what would be the harm of allowing
          access to a member ( a member that was declared in the B class in your
          example above) that we know must exist, no matter what subclass the
          object actually belongs to (D1, D2, a subclass of D2, etc.)?

          Comment

          • blangela

            #6
            Re: Why can derived member function not access protected member of abase class object?

            On Sep 25, 1:25 pm, blangela <Bob_Langel...@ telus.netwrote:
            On Sep 25, 12:55 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
            >
            >
            >
            >
            >
            blangela wrote:
            If I pass a base class object by reference (likely does not make a
            difference here that it is passed by reference) as a parameter to a
            derived class member function, the member function is not allowed to
            access the protected data members of the base object. This surprises
            me.
            >
            Can someone explain why this is?  I suspect there is a good reason and
            I am just having a slow day to not come up with it myself.
            >
            Isn't this in the FAQ?  It should be.
            >
            In short, the reason is to prevent access to members of a different type
            (across the hierarchy).  If D1 and D2 derive from B, an instance of D1
            is not allowed to access any non-public members of D2 (unless they are
            friends, of course).  When you pass a reference to B to a member
            function of D1, the access to members of that class is blocked because
            it *can* be a subobject of a D2 object, and not necessarily of another
            D1.  Need an example?  Look in the archives, we had that topic discussed
            several times over the past years.
            >
            V
            --
            Please remove capital 'A's when replying by e-mail
            I do not respond to top-posted replies, please don't ask
            >
            Even with the example you supply, what would be the harm of allowing
            access to a member ( a member that was declared in the B class in your
            example above) that we know must exist, no matter what subclass the
            object actually belongs to (D1, D2, a subclass of D2, etc.)?- Hide quotedtext -
            >
            - Show quoted text -
            Also, I changed the member function to:

            void Derived::Method 4(Base & B_Param)
            {
            Derived * DPtr = dynamic_cast <Derived *(&B_Param); // this cast
            // creates a Derived class pointer to B_Param, if and only if,
            // B_Param actually is Derived class object, otherwise the
            // pointer will be set to 0

            if (DPtr != 0) // if B_Param is actually a Derived class object
            cout << DPtr->mDerived << endl;
            else
            {
            Base B_obj = B_Param;
            cout << B_obj.mBase << endl;
            }
            }

            And I still have the same errors:

            1>c:\documents and settings\blange la\desktop\poly morphismtest
            \derived.cpp(29 ) : error C2248: 'Base::mBase' : cannot access
            protected member declared in class 'Base'
            1 c:\documents and settings\blange la\desktop\poly morphismtest
            \base.h(17) : see declaration of 'Base::mBase'
            1 c:\documents and settings\blange la\desktop\poly morphismtest
            \base.h(7) : see declaration of 'Base'

            I would have thought that B_obj can only be a Base object now (and not
            some subclass of Base), that it would now be allowed?

            Comment

            • news.aioe.org

              #7
              Re: Why can derived member function not access protected member ofa base class object?

              blangela wrote:
              If I pass a base class object by reference (likely does not make a
              difference here that it is passed by reference) as a parameter to a
              derived class member function, the member function is not allowed to
              access the protected data members of the base object. This surprises
              me.
              >
              Can someone explain why this is? I suspect there is a good reason and
              I am just having a slow day to not come up with it myself.
              >
              Bob
              I know this is a C++ group and I hope I won't offend anyone by saying unlike in
              C++ this kind of access is perfectly allowed in Java.

              Comment

              • Jeff Schwab

                #8
                Re: Why can derived member function not access protected member ofa base class object?

                news.aioe.org wrote:
                blangela wrote:
                >If I pass a base class object by reference (likely does not make a
                >difference here that it is passed by reference) as a parameter to a
                >derived class member function, the member function is not allowed to
                >access the protected data members of the base object. This surprises
                >me.
                >>
                >Can someone explain why this is? I suspect there is a good reason and
                >I am just having a slow day to not come up with it myself.
                I know this is a C++ group and I hope I won't offend anyone by saying
                unlike in C++ this kind of access is perfectly allowed in Java.
                Er... You sure about that? Is it possible that you just tried a toy
                example with two classes in the same (e.g. top-level) package, and
                forgot that "protected" in Java grants access to all classes in the same
                package?

                Comment

                • news.aioe.org

                  #9
                  Re: Why can derived member function not access protected member ofa base class object?

                  Jeff Schwab wrote:
                  news.aioe.org wrote:
                  >blangela wrote:
                  >>If I pass a base class object by reference (likely does not make a
                  >>difference here that it is passed by reference) as a parameter to a
                  >>derived class member function, the member function is not allowed to
                  >>access the protected data members of the base object. This surprises
                  >>me.
                  >>>
                  >>Can someone explain why this is? I suspect there is a good reason and
                  >>I am just having a slow day to not come up with it myself.
                  >
                  >I know this is a C++ group and I hope I won't offend anyone by saying
                  >unlike in C++ this kind of access is perfectly allowed in Java.
                  >
                  Er... You sure about that? Is it possible that you just tried a toy
                  example with two classes in the same (e.g. top-level) package, and
                  forgot that "protected" in Java grants access to all classes in the same
                  package?
                  Yikes, I am embarrassed. That is exactly what I did! So it is consistent
                  between the two languages. When I moved the base class to a different package,
                  compiler throws an error:
                  x has protected access in package1.Base

                  Thanks for pointing out my mistake.

                  Comment

                  • Victor Bazarov

                    #10
                    Re: Why can derived member function not access protected member ofa base class object?

                    blangela wrote:
                    [..]
                    Also, I changed the member function to:
                    >
                    void Derived::Method 4(Base & B_Param)
                    {
                    Derived * DPtr = dynamic_cast <Derived *(&B_Param); // this cast
                    // creates a Derived class pointer to B_Param, if and only if,
                    // B_Param actually is Derived class object, otherwise the
                    // pointer will be set to 0
                    >
                    if (DPtr != 0) // if B_Param is actually a Derived class object
                    cout << DPtr->mDerived << endl;
                    else
                    {
                    Base B_obj = B_Param;
                    cout << B_obj.mBase << endl;
                    }
                    }
                    >
                    And I still have the same errors:
                    >
                    1>c:\documents and settings\blange la\desktop\poly morphismtest
                    \derived.cpp(29 ) : error C2248: 'Base::mBase' : cannot access
                    protected member declared in class 'Base'
                    1 c:\documents and settings\blange la\desktop\poly morphismtest
                    \base.h(17) : see declaration of 'Base::mBase'
                    1 c:\documents and settings\blange la\desktop\poly morphismtest
                    \base.h(7) : see declaration of 'Base'
                    >
                    I would have thought that B_obj can only be a Base object now (and not
                    some subclass of Base), that it would now be allowed?
                    You changes the run-time behaviour of your program, but not the logic
                    for that particular statement. The rules of the language do not depend
                    on the run-time behaviour. The compiler is not going to verify the
                    run-time conditions when it checks the semantics of an expression.
                    Access is prohibited, period. It does not matter whether the *actual*
                    type of the super-object is the same or not because in general it isn't.

                    V
                    --
                    Please remove capital 'A's when replying by e-mail
                    I do not respond to top-posted replies, please don't ask

                    Comment

                    • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

                      #11
                      Re: Why can derived member function not access protected member ofa base class object?

                      On 2008-09-25 22:25, blangela wrote:
                      On Sep 25, 12:55 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
                      >blangela wrote:
                      If I pass a base class object by reference (likely does not make a
                      difference here that it is passed by reference) as a parameter to a
                      derived class member function, the member function is not allowed to
                      access the protected data members of the base object. This surprises
                      me.
                      >>
                      Can someone explain why this is? I suspect there is a good reason and
                      I am just having a slow day to not come up with it myself.
                      >>
                      >Isn't this in the FAQ? It should be.
                      >>
                      >In short, the reason is to prevent access to members of a different type
                      >(across the hierarchy). If D1 and D2 derive from B, an instance of D1
                      >is not allowed to access any non-public members of D2 (unless they are
                      >friends, of course). When you pass a reference to B to a member
                      >function of D1, the access to members of that class is blocked because
                      >it *can* be a subobject of a D2 object, and not necessarily of another
                      >D1. Need an example? Look in the archives, we had that topic discussed
                      >several times over the past years.
                      Please do not quota signatures.
                      Even with the example you supply, what would be the harm of allowing
                      access to a member ( a member that was declared in the B class in your
                      example above) that we know must exist, no matter what subclass the
                      object actually belongs to (D1, D2, a subclass of D2, etc.)?
                      Since the members are not public it means that the only means of
                      changing them should be through the interface (public member functions)
                      of the class. If arbitrarily could change some member just of a class
                      just because that class had the same ancestor as you there would be not
                      way for that class to ensure it does not end up in an invalid state.
                      Just because the value of a member of the base-class is valid in one
                      derived class does not mean that it is valid in another derived class.

                      --
                      Erik Wikström

                      Comment

                      Working...