In the first case the access check is done (as it is always done) on the static type that the call is made through. The static type of *b
is base
, and in that case doSomething()
is public
.
C++03 11.6 "Access to virtual functions" says:
The access rules (clause 11) for a virtual function are determined by
its declaration and are not affected by the rules for a function that
later overrides it. [Example:
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); //OK:B::f()is public,
// D::f() is invoked
pd->f(); //error:D::f()is private
}
—end example]
Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.
Keep in mind especially that "the access of the member function in the class in which it was defined (D in the example above) is in general not known". In general, at the point in your example where b->doSomething();
is called, the compiler may have no knowledge at all about derived
(or child
), much less whether or not the access to derived::doSomething()
is private.