Say that a base class A
defines a protected member. A derived class B
uses this member.
class A
{
public:
A(int v) : value(v) { }
There is actually a loophole using member pointers (no casting, no copying):
void B::compare_and_print(const A& other) const
{
auto max_value = std::max(value, other.*(&B::value));
std::cout << "Max value: " << max_value << "\n";
}
You can bypass protected by using a helper struct:
struct A_Helper : public A
{
static int GetProtectedValue(const A & a)
{
return static_cast<const A_Helper&>(a).Value;
}
};
You can get it by using it anywhere A_Helper::GetProtectedValue(a)
In your case, you could cast other
to const B&
(via static_cast
or reinterpret_cast
) but you don't know if instance of other
is of type B
. With that casted value people reading the code would presume that other
is of type B
and could insert code that causes reads/writes to "random" memory.
Consider that class B
has another memeber value_B
and other
is of type C
. Using static_cast<const B&>(other).value_B
is Undefined Behavior.