Tutorial :Accessing protected members in a derived class



Question:

I ran into an error yesterday and, while it's easy to get around, I wanted to make sure that I'm understanding C++ right.

I have a base class with a protected member:

class Base  {    protected:      int b;    public:      void DoSomething(const Base& that)      {        b+=that.b;      }  };  

This compiles and works just fine. Now I extend Base but still want to use b:

class Derived : public Base  {    protected:      int d;    public:      void DoSomething(const Base& that)      {        b+=that.b;        d=0;      }  };  

Note that in this case DoSomething is still taking a reference to a Base, not Derived. I would expect that I can still have access to that.b inside of Derived, but I get a cannot access protected member error (MSVC 8.0 - haven't tried gcc yet).

Obviously, adding a public getter on b solved the problem, but I was wondering why I couldn't have access directly to b. I though that when you use public inheritance the protected variables are still visible to the derived class.


Solution:1

You can only access protected members in instances of your type (or derived from your type).
You cannot access protected members of an instance of a parent or cousin type.

In your case, the Derived class can only access the b member of a Derived instance, not of a different Base instance.

Changing the constructor to take a Derived instance will also solve the problem.


Solution:2

You have access to the protected members of Derived, but not those of Base (even if the only reason it's a protected member of Derived is because it's inherited from Base)


Solution:3

As mentioned, it's just the way the language works.

Another solution is to exploit the inheritance and pass to the parent method:

class Derived : public Base  {    protected:      int d;    public:      void DoSomething(const Base& that)      {        Base::DoSomething(that);        d=0;      }  };  


Solution:4

protected members can be accessed:

  • through this pointer
  • or to the same type protected members even if declared in base
  • or from friend classes, functions

To solve your case you can use one of last two options.

Accept Derived in Derived::DoSomething or declare Derived friend to Base:

class Derived;    class Base  {    friend class Derived;    protected:      int b;    public:      void DoSomething(const Base& that)      {        b+=that.b;      }  };    class Derived : public Base  {    protected:      int d;    public:      void DoSomething(const Base& that)      {        b+=that.b;        d=0;      }  };  

You may also consider public getters in some cases.


Solution:5

class Derived : public Base  {    protected:      int d;    public:      void DoSomething()      {        b+=this->b;        d=0;      }  };    //this will work  


Solution:6

You can try with static_cast< const Derived*>(pBase)->Base::protected_member ...

class Base  {    protected:      int b;      public:      ...  };    class Derived : public Base  {    protected:      int d;      public:      void DoSomething(const Base& that)      {        b += static_cast<const Derived*>(&that)->Base::b;        d=0;      }      void DoSomething(const Base* that)      {        b += static_cast<const Derived*>(that)->Base::b;        d=0;      }  };  


Solution:7

Use this pointer to access protected members

class Derived : public Base  {    protected:      int d;    public:      void DoSomething(const Base& that)      {        this->b+=that.b;        d=0;      }  };  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »