Видимость частного доступа / доступ в C ++ - PullRequest
1 голос
/ 14 октября 2019

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

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

Я не понимаю, почему метод наследует какую-то видимость из-за частного наследования. Вполне разумно, что у производного класса нет доступа к 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 ]

3 голосов
/ 14 октября 2019

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

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

1 голос
/ 14 октября 2019

В соответствии со стандартом 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
};

- конец примера]

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...