Let's consider a code example showing what would be allowed (or not) using different levels of inheritance:
class BaseClass {};
void freeStandingFunction(BaseClass* b);
class DerivedProtected : protected BaseClass
{
DerivedProtected()
{
freeStandingFunction(this); // Allowed
}
};
DerivedProtected
can pass itself to freeStandingFunction
because it knows it derives from BaseClass
.
void freeStandingFunctionUsingDerivedProtected()
{
DerivedProtected nonFriendOfProtected;
freeStandingFunction(&nonFriendOfProtected); // NOT Allowed!
}
A non-friend (class, function, whatever) cannot pass a DerivedProtected
to freeStandingFunction
, because the inheritance is protected, so not visible outside derived classes. Same goes for private inheritance.
class DerivedFromDerivedProtected : public DerivedProtected
{
DerivedFromDerivedProtected()
{
freeStandingFunction(this); // Allowed
}
};
A class derived from DerivedProtected
can tell that it inherits from BaseClass
, so can pass itself to freeStandingFunction
.
class DerivedPrivate : private BaseClass
{
DerivedPrivate()
{
freeStandingFunction(this); // Allowed
}
};
The DerivedPrivate
class itself knows that it derives from BaseClass
, so can pass itself to freeStandingFunction
.
class DerivedFromDerivedPrivate : public DerivedPrivate
{
DerivedFromDerivedPrivate()
{
freeStandingFunction(this); // NOT allowed!
}
};
Finally, a non-friend class further down the inheritance hierarchy cannot see that DerivedPrivate
inherits from BaseClass
, so cannot pass itself to freeStandingFunction
.