This is about "protected", which is explained as: "When a class inherits another one, the members of the derived class can access the protected members inherited from the base class." However, look at this code:
class Base {
public:
Base( int m ) : member(m){}
protected:
int member;
};
class Derived : public Base { // one of several subclasses
public:
Derived( int m ) : Base(m), value(10) {}
int diff( Base x ){
return value - x.member;
}
private:
int value;
};
Derived accesses "x.member", which is protected in its Base class, right? But the compiler flags an error, "Base::member is protected". And, after mulling this over for a minute, I had to agree with the compiler.
And here comes the question: How do I make this work, with a minimum loss of information hiding?
Did I miss something?
You can use a static protected accessor:
class Base {
public:
Base( int m ) : member(m){}
private:
int member;
protected:
static int GetMember(const Base &b)
{ return b.member; }
};
class Derived : public Base { // one of several subclasses
public:
Derived( int m ) : Base(m), value(10) {}
int diff( Base &x ){ //beware of your slicing!
return value - GetMember(x);
}
private:
int value;
};
Now let me add my idea of why C++ access control works this way...
Access control in C++ is not about information hiding. It is about encapsulation. That is, plainly speaking, you filter out the access to any member that can break the class if used incorrectly.
In an ideal class
As you see, in my scheme there is little place for protected members:
And even less place for protected member variables.
So make your variable private, and write a protected accessor. The accessor must be static to be able to be used from the derived object.