I came across this issue accidentally when I was going over inheritance and up/down casting. Why is this not allowed (code is commented to show sections that are not allowed)? Now I can guess as to why it is not allowed but a factual answer would be great.
As for the code that is allowed, I know it is because (Base*) is a C-style cast which is essentially a reinterpret_cast in C++ which in turn means that in this case it will result in undefined behavior. Please correct me if I am wrong.
class Base
{
};
class Derived : public Base
{
};
class DerivedProt : protected Base
{
};
class DerivedPriv : private Base
{
};
int main()
{
Base* a = new Derived();
Base* b = new DerivedProt(); // Not allowed
Base* c = new DerivedPriv(); // Not allowed
Base* d = (Base*) new DerivedProt(); // Allowed but undefined behavior...?
Base* e = (Base*) new DerivedPriv(); // Allowed but undefined behavior...?
}
Sounds like you are correct.
One thing to remember is that traditional OO principles such as the LSP only describe public inheritance. Non-public inheritance falls in-between inheritance and composition, the base subobject is non-public like composition, but you can also take advantage of features which rely on inheritance, such as virtual functions.
Just like a composed subobject, however, only the class (or its descendants, in case of protected inheritance), can get the address of the subobject.