Because A is making the call to otherA.hello();. You cannot call into it private or protected code directly, but descendants of A, including A itself, can call into A (descendants cannot access A's private data/methods, but A can access A's private data/methods). Relatedly, A can also access the private data/methods of other instances of A (this is generally how copy constructors and assignment operators work).
In fact, it's the ability to use protected code within the class that enables the creation of some very powerful OO concepts. With that said, I see it as an abuse to call an inner-object's private or protected methods even when possible, but using them directly against yourself is hopefully by design rather than convenience.
In C++, you can provide abstract implementations of classes (or structs for that matter) by marking items as virtual and not providing an implementation.
class A
{
public:
void set_value(const std::string &value)
{
if (is_valid(value))
{
this->value = value;
}
}
const std::string &get_value() const
{
return value;
}
protected:
virtual boolean is_valid(const std::string &value) const = 0;
private:
std::string value;
}
Then
class B : public A
{
protected:
virtual boolean is_valid(const std::string &value) const
{
return value != "abc";
}
}
Notice that A is setup to inherit functionality, and it is built to anticipate it being supplied (granted the example above doesn't really provide a lot of utility, but it does show what I mean).