Потому что, хотите верьте, хотите нет, вы не хотите связывать B с деталями реализации A. Представьте сценарий с самым простым видом использования:
struct A
{
protected:
int x;
};
struct B
{
void f() { ... access x and use as input ... }
};
Теперь давайте предположим, чтотребуется изменение вашего продукта, и теперь A не имеет переменной x, а вместо этого выбирает значение x, которое должно быть представлено каким-либо другим способом, возможно, составом.Поскольку B обращается к члену напрямую, вы должны изменить любой B, который вы создали, чтобы захватить x через любой новый механизм, который не существует.Чем больше вам нужно изменить, тем больше места для проблем.
Если бы вы вместо этого сделали xa приватным участником и предоставили защищенный получатель, у вас не было бы этой проблемы.
Опять же,это самый простой пример.В общем, такие значения, как x, используются в реализации поведения A, и B не должен заботиться о том, как реализовано поведение, и при этом он не должен иметь доступа к нему.