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

Discussion in 'C++' started by blangela, Sep 25, 2008.

  1. blangela

    blangela Guest

    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, Sep 25, 2008
    #1
    1. Advertising

  2. blangela

    blangela Guest

    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(Base & B_Param)
    {
    cout << (B_Param.mBase) * (this->mBase) << endl;
    }

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

    void Base::Method3(Derived & D_Param)
    {
    Base & BRef = static_cast<Base &>(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::Derived()
    {
    this->mBase = 3;
    this->mDerived = 5;
    }

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

    void Derived::Method4(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\blangela\desktop\polymorphismtest
    \derived.cpp(27) : error C2248: 'Base::mBase' : cannot access
    protected member declared in class 'Base'
    1> c:\documents and settings\blangela\desktop\polymorphismtest
    \base.h(17) : see declaration of 'Base::mBase'
    1> c:\documents and settings\blangela\desktop\polymorphismtest
    \base.h(7) : see declaration of 'Base'
    blangela, Sep 25, 2008
    #2
    1. Advertising

  3. blangela

    blangela Guest

    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::Method4(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;
    }
    blangela, Sep 25, 2008
    #3
  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?


    Because that's what the language standard requires with regard to
    protected access. The language specification is trying to make sure that
    base class members you are trying to access are actually members of a
    base class subobject within that specific derived class.

    In order to enforce that requirement, protected base class members are
    only accessible through objects of the derived class type.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Sep 25, 2008
    #4
  5. blangela

    blangela Guest

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

    On Sep 25, 12:55 pm, Victor Bazarov <> 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.

    >
    > 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.)?
    blangela, Sep 25, 2008
    #5
  6. blangela

    blangela Guest

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

    On Sep 25, 1:25 pm, blangela <> wrote:
    > On Sep 25, 12:55 pm, Victor Bazarov <> 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.

    >
    > > 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 quoted text -
    >
    > - Show quoted text -


    Also, I changed the member function to:

    void Derived::Method4(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\blangela\desktop\polymorphismtest
    \derived.cpp(29) : error C2248: 'Base::mBase' : cannot access
    protected member declared in class 'Base'
    1> c:\documents and settings\blangela\desktop\polymorphismtest
    \base.h(17) : see declaration of 'Base::mBase'
    1> c:\documents and settings\blangela\desktop\polymorphismtest
    \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?
    blangela, Sep 25, 2008
    #6
  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.
    news.aioe.org, Sep 25, 2008
    #7
  8. 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.
    news.aioe.org, Sep 26, 2008
    #8
  9. 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 <> 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.

    >>
    >> 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
    Erik Wikström, Sep 26, 2008
    #9
    1. Advertising

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. Steven T. Hatton
    Replies:
    2
    Views:
    402
    tom_usenet
    Aug 16, 2004
  2. Siemel Naran
    Replies:
    4
    Views:
    785
    Micah Cowan
    Jan 12, 2005
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,754
    Smokey Grindel
    Dec 2, 2006
  4. NewToCPP
    Replies:
    3
    Views:
    371
    NewToCPP
    Aug 30, 2006
  5. Jaco Naude
    Replies:
    8
    Views:
    658
    Paul N
    Sep 28, 2010
Loading...

Share This Page