Доступ не наследуется. Это чаще упоминается при обсуждении друзей , но это также применимо и здесь.
Сначала давайте посмотрим, почему Foo::Utility::action
может получить доступ к закрытому классу Foo::Container
.На самом деле, это прямо там, в именах.Foo::Container
могут быть доступны только членам Foo
, а члены Foo
могут быть распознаны, когда вы записываете их квалифицированные имена, и это имя начинается с "Foo::
".
В отличие от этого, UtilityPrint
не является членом Foo
.(На самом деле, было бы огромным нарушением безопасности, если бы кто-то мог просто сказать «о, да, я тоже член!» и получить доступ к вашей личной информации.) Так что пока UtilityPrint
имеет(защищенный) доступ к Foo::Utility
, он не имеет доступа ко всему, к чему Foo::Utility
имеет доступ.
Если Foo::Utility
хочет расширить свой доступ к классам, производным от него, ему потребуется явноСделай так.Один из способов сделать это - создать псевдоним.
class Utility {
protected:
using Container = Foo::Container; // Derived classes can access this.
public:
virtual void action(Container &) = 0;
virtual ~Utility() {} // <-- remember to properly support polymorphism
};
Это все еще оставляет открытым вопрос о том, является ли это хорошим дизайном.Я бы посчитал это предупреждением о том, что что-то может быть отключено, но не совсем так.Вопрос не имеет достаточного контекста для меня, чтобы сделать такой вызов.Я бы просто дал вам указание, что если вы чувствуете, что обходите многие языковые функции (например, частный доступ), то, возможно, дизайн нуждается в работе.