Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protected/Private Inheritance Casting

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...?
}
like image 313
Samaursa Avatar asked Mar 20 '11 22:03

Samaursa


2 Answers

The Standard explicitly specifies that C-style casts may perform this conversion. It's the only cast which C-style casts can do but no C++ cast can do. The results are not undefined a far as I know; it's just not allowed by any other cast.

like image 179
Puppy Avatar answered Sep 22 '22 22:09

Puppy


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.

like image 27
Ben Voigt Avatar answered Sep 24 '22 22:09

Ben Voigt