Видимость / доступ частного наследования в C++

Почему интерфейс имеет особую видимость в методе из-за частного наследования?

Обратите внимание, что в моем производном классе требуется глобальный спецификатор ::.

Я не понимаю, почему метод наследует видимость из-за частного наследования. Совершенно разумно, что класс Derived не имеет доступа к Control. Но почему он также не имеет доступа через участника?

class Control
{
public:
    void ModifySomething();
};

class Base : private Control
{
private:
    virtual void Update( Control& i_control );
};

class Derived : public Base
{
private:
    // ----------↓↓
    void Update( ::Control& i_control ) override;
};

Примечание: я понимаю, что мы можем исправить это с помощью композиции. Но я хотел бы знать, почему он так определен в C++. Можем ли мы нарушить постоянство или что-то в этом роде?

2 ответа

Решение

Согласно стандарту C++ 17 (спецификаторы доступа 14.1)

5 [Примечание. В производном классе поиск имени базового класса найдет имя внедренного класса вместо имени базового класса в той области видимости, в которой он был объявлен. Имя внедренного класса может быть менее доступным, чем имя базового класса в области, в которой он был объявлен. - конец примечания]

И есть пример, похожий на ваш фрагмент кода.

[Пример:

class A { };
class B : private A { };
class C : public B {
  A* p; // error: injected-class-name A is inaccessible
  ::A* q; // OK
};

- конечный пример]

Это имя внедренного класса частного базового класса в определении производного класса скрывает имя базового класса, определенного в пространстве имен. И это введенное имя является личным. Таким образом, производный класс не имеет доступа к этому частному введенному имени.

class Derived не имеет доступа ни к чему private в class Base, поэтому у него нет доступа к class Control через Base. Однако он может получить доступControl напрямую, потому что он объявлен в той же глобальной области видимости, что и Derived.

Как отмечает @ previouslyknownas_463035818, есть два пути к Control от Derived но один заблокирован из-за private контроль доступа, поэтому выбирается другой, глобальный путь.

Другие вопросы по тегам