Even though access control in C++ works on per-class basis (as opposed to per-instance basis), protected
access specifier has some peculiarities.
The language specification wants to ensure that you are accessing a protected member of some base subobject that belongs to the derived class. You are not supposed to be able access protected members of some unrelated independent objects of base type. In particular, you cannot access protected members of freestanding objects of base type. You are only allowed to access protected members of base objects that are embedded into derived objects as base subobjects.
For this reason, you have to access protected members through pointer->member
syntax, reference.member
or object.member
syntax, where the pointer/reference/object refers to the derived class.
This means that in your example, protected member somethingProtected()
is not accessible through Base
objects, Base *
pointers or Base &
references, but it is accessible through Derived
objects, Derived *
pointers and Derived &
references. Your plain somethingProtected()
access is allowed, since it is just a shorthand for this->somethingProtected()
where this
is of type Derived *
.
b.somethingProtected()
violates the above requirements.
Note that in accordance with the above rules in
void Derived::somethingDerived()
{
Base *b = this;
b->somethingProtected(); // ERROR
this->somethingProtected(); // OK
}
the first call will also fail while the second one will compile, even though both are trying to access the same entity.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…