Search code examples
c++castingprotected

Access protected members of an existing base object


Lets say I have a base class with protected member:

class Base  
{
public:
    Base(int data)
    : m_attribute(data) {}

protected:
    int m_attribute;
};

and derived class from base:

class Derived : public Base 
{
 public:
    int get_attribute()
    {
        return m_attribute;
    }   
};

First of all: I can do this, right? Is this totally legal?

If yes, then here is the question:

  • I can't change anything in a Base class;
  • I have a Base class object, and I need to access its m_attribute member;

Should I do downcasting from this base class object to derived class object first, and then call get_attribute() function? Something like this:

Base base(5);
Derived* derived = static_cast < Derived*>(&base);
int base_attribute = derived->get_attribute();

Or what are other ways to access protected member? I know that friend function is an option, but I can't change anything in the base class


Solution

  • Should I do downcasting from this base class object to derived class object first, and then call get_attribute() function?

    Most definitely not. An instance of a base class is not an instance of a derived class. Your conversion is ill-formed.

    Here is a valid way:

    struct kludge : Base {
        kludge(const Base& b): Base(b) {}
        operator int() {
            return m_attribute;
        }
    };
    

    usage:

    Base base(5);
    int foo = kludge(base);
    

    This kludge works by copy constructing the base sub object of the derived type. This of course depends on the base being copyable - which your Base is. It's easy to tweak to work with movable as well.

    As a syntactic sugar, the kludge is implicitly convertible to the type of the member. If you prefer, you could use a getter.