* Daniel Aarno:
Can anyone provide a good explanation to why the following does not
work? After all since A is a public base of B objects of type B ISA
object of type A.
class A {
protected:
void foo() {}
};
class B : public A {
public:
void bar(A &a, B &b) {
foo(); //< OK, accessing A::foo in *this
b.foo(); //< OK, accessing A::foo in other object of type B
a.foo(); //< ERROR: foo() is protected in this context
}
}
It's not 100% clear-cut, but a practical language design decision.
Consider a class B2 also deriving from A, and
class B: public A
{
void bar( A& a, B2 &b2 )
{
}
}
Why shouldn't code in class B be able to access the protected member
in 'b2'?
Well, we don't know that that's safe, in any way. In class B2 it might
be a requirement that the object is in a certain state before the
call. Or it might be that some further action is required after the
call to bring 'b2' to a valid external state; the function is protected
precisely because its usage requires knowledge of and access to the
the inner workings of the object, which is the opposite of encapsulation.
Now consider your original example, but called with an object of class C
as actual argument for 'b', where class C is derived from B. Again the
code in class B doesn't know whether its safe to call the protected
member function, because class C might have imposed additional requirements.
The reason this is not 100% clear-cut is that class B might have as part
of its contract that no derived class should change the requirements.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?