Базовый класс - недоступная ошибка, почему частное наследование делает это? - PullRequest
0 голосов
/ 28 сентября 2019
class a
{
public:
    int var;
};

class b : a
{
};

int main()
{
    a* p = new b();

    return 0;
}

Я знаю, что это вызвано частным наследством, но я хочу знать, почему это так?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Это то, что означает «частное» в частном наследовании.Тот факт, что b наследуется от a, является деталью реализации и не виден извне.

Я не пытаюсь получить доступ к любому закрытому члену вне класса или к любому защищенному внешнему элементу иерархии классов, я просто пытаюсь создать динамический объект с указателем базового класса, и он вызываетошибка

Вы пытаетесь получить доступ к преобразованию из b* в a*, но не можете этого сделать, поскольку извне базовый класс недоступен.Частное наследство ближе к составу, чем к публичному наследованию.Ваш пример может быть переписан как

class b {
      a a_instance;
};

Реализация b будет немного отличаться (потому что вызов a функций-членов осуществляется через a_instance вместо this), но эффектто же самое: мы составляем b из a, и пользователи не знают об этом (он же private).

0 голосов
/ 28 сентября 2019

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

Из стандарта C ++ 17 (14.2 Доступность базовых классов и членов базового класса)

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

В этом объявлении

a* p = new b();

при попытке доступа к закрытому подобъекту типа a объекта типа b, поскольку статический тип указателя p равен a *.

Фактически это утверждение

a* p = new b();

имеет ту же семантику, что и, например,

class A
{
private:
    int x = 10;
};

A a;
int *p = &a.x;

Если это разрешено, то с помощью указателя вы можете изменить частный подобъект объекта.объект.

...