When you specify a base class as private, it affects only nonstatic members. Public static members are still accessible in the derived classes. However, accessing members of the base class using pointers, references, or objects can require a conversion, at which time access control is again applied. Consider the following example:
class Base
{
public:
int Print(); // Nonstatic member.
static int CountOf(); // Static member.
};
// Derived1 declares Base as a private base class.
class Derived1 : private Base
{
};
// Derived2 declares Derived1 as a public base class.
class Derived2 : public Derived1
{
int ShowCount(); // Nonstatic member.
};
// Define ShowCount function for Derived2.
int Derived2::ShowCount()
{
// Call static member function CountOf explicitly.
int cCount = Base::CountOf(); // OK.
// Call static member function CountOf using pointer.
cCount = this->CountOf(); // Error. Conversion of
// Derived2 * to Base * not
// permitted.
return cCount;
}
In the preceding code, access control prohibits conversion from a pointer to Derived2
to a pointer to Base
. The this pointer is implicitly of type Derived2 *
. To select the CountOf
function, this must be converted to type Base *
. Such a conversion is not permitted because Base
is a private indirect base class to Derived2
. Conversion to a private base class type is acceptable only for pointers to immediate derived classes. Therefore, pointers of type Derived1 *
can be converted to type Base *
.
Note that calling the CountOf
function explicitly, without using a pointer, reference, or object to select it, implies no conversion. Therefore, the call is allowed.
Members and friends of a derived class, T, can convert a pointer to T to a pointer to a private direct base class of T.