In order to be able to cast from a class to a parent class, the public members of the parent class must be available. More exactly, the public members of the parent must be callable when calling them on the child class to whoever is casting it.
You can ask yourself this question: if I create an object of type B
, can I call a public method of D_prot
? If the answer is yes, then you can cast it, e.g.:
class A
{
public:
void foo();
};
class B : public A
{
};
// Then when someone has a B object:
B b;
b.foo(); // Are we allowed to call foo()?
static_cast<A>(b).foo(); // If yes, we can cast it as well
A more exhaustive version looks like this:
class Base
{
public:
void foo() {} // Dummy method to clarify the example
};
class PublicChild : public Base
{
public:
void test()
{
foo(); // OK, we have access to Base public members
static_cast<Base*>(this)->foo(); // OK
}
friend class PublicFriend;
};
class PublicFriend
{
void test(PublicChild* p)
{
p->foo(); // OK, the method is public anyway
static_cast<Base*>(p)->foo(); // OK
}
};
class ProtectedChild : protected Base
{
public:
void test()
{
foo(); // OK, we have access to Base public members
static_cast<Base*>(this)->foo(); // OK
}
friend class ProtectedFriend;
};
class ProtectedFriend
{
void test(ProtectedChild* p)
{
p->foo(); // OK, because we are a friend of ProtectedChild, we have the same visibility as ProtectedChild itself
static_cast<Base*>(p)->foo(); // OK
}
};
class PrivateChild : private Base
{
public:
void test()
{
foo(); // OK, we have access to Base public members
static_cast<Base*>(this)->foo(); // OK
}
friend class PrivateFriend;
};
class PrivateFriend
{
void test(PrivateChild* p)
{
p->foo(); // OK, because we are a friend of PrivateChild, we have the same visibility as PrivateChild itself
static_cast<Base*>(p)->foo(); // OK
}
};
int main()
{
Base b;
b.foo(); // OK: public method
PublicChild p1;
p1.foo(); // OK: public inheritance makes Base::foo public
static_cast<Base>(p1).foo(); // OK
ProtectedChild p2;
p2.foo(); // error: protected inheritance makes Base::foo protected
static_cast<Base>(p2).foo(); // error
PrivateChild p3;
p3.foo(); // error: private inheritance makes Base::foo private
static_cast<Base>(p3).foo(); // error
}
Example: https://ideone.com/Zbaqbu
PS.in the link I have commented the lines which do not compile, feel free to fork the code and uncomment them to see what the compiler tells