Защищенное наследование позволяет производному классу получить доступ к частным членам его базового класса?

Я действительно запутался в частном наследовании и защищенном наследовании.

1) в защищенном наследовании, общественные и защищенные члены становятся защищенными членами в производном классе. В частном наследстве все частное. Однако производный класс никогда не сможет получить доступ к частным членам базового класса, верно? Полученный класс может получить доступ к публичным и защищенным членам в обоих случаях. Это правильно?

2) Я заметил, что частные члены базового класса никогда не будут затронуты производным классом. Итак, почему унаследованные частные члены?

Ответ 1

Вы верны в пункте №1. Указание private, protected или public при наследовании от базового класса не изменяет ничего доступного по самому производному классу. Эти спецификаторы доступа сообщают компилятору, как обращаться с членами базового класса, когда экземпляры производного класса используются в другом месте, или если производный класс используется в качестве базового класса для других классов.

ОБНОВЛЕНИЕ: Следующие примеры могут помочь проиллюстрировать различия:

class Base
{
    private:   int base_pri;
    protected: int base_pro;
    public:    int base_pub;
};

Для классов, полученных из базы:

class With_Private_Base :   private Base   { void memberFn(); };
class With_Protected_Base : protected Base { void memberFn(); };
class With_Public_Base :    public Base    { void memberFn(); };

// this would be the same for all of the above 3 classes:
void With_PXXX_Base::memberFn()
{
    base_pri = 1; // error: `int Base::base_pri' is private
    base_pro = 1; // OK
    base_pub = 1; // OK
}

Для классов, полученных из 3 производных классов:

class A : public With_Private_Base { void memberFn(); }
void A::memberFn()
{
    base_pri = 1; // error: `int Base::base_pri' is private
    base_pro = 1; // error: `int Base::base_pro' is protected
    base_pub = 1; // error: `int Base::base_pub' is inaccessible
}

class B : public With_Protected_Base { void memberFn(); }
void B::memberFn()
{
    base_pri = 1; // error: `int Base::base_pri' is private
    base_pro = 1; // OK
    base_pub = 1; // OK
}

class C : public With_Public_Base { void memberFn(); }
void C::memberFn()
{
    base_pri = 1; // error: `int Base::base_pri' is private
    base_pro = 1; // OK
    base_pub = 1; // OK
}

Внешний доступ к первым трем производным классам:

void main()
{
    With_Private_Base   pri_base;
    pri_base.base_pri = 1; // error: `int Base::base_pri' is private
    pri_base.base_pro = 1; // error: `int Base::base_pro' is protected
    pri_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible

    With_Protected_Base pro_base;
    pro_base.base_pri = 1; // error: `int Base::base_pri' is private
    pro_base.base_pro = 1; // error: `int Base::base_pro' is protected
    pro_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible

    With_Public_Base    pub_base;
    pub_base.base_pri = 1; // error: `int Base::base_pri' is private
    pub_base.base_pro = 1; // error: `int Base::base_pro' is protected
    pub_base.base_pub = 1; // OK
}

Ответ 2

1a) Защищенное наследование означает, что "ребенок" может получить доступ ко всему, что может быть в публичном наследовании, но другие, использующие этот объект, могут видеть только открытый интерфейс для ребенка, что-то в нем родительский скрыт.

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

2) Частные члены наследуются, потому что им могут понадобиться методы в базовом классе.

Ответ 3

  • Да, это правильно. Производные классы могут обращаться к защищенным и открытым членам этого базового класса, а производный класс не может получить доступ к частным членам его базового класса.

  • Частные члены наследуются по следующей причине: базовый класс может определять защищенную или публичную функцию, которая модифицирует частный член базового класса. Производный класс может вызывать эту функцию и поэтому должен знать о частной переменной, к которой он обращается.

Ответ 4

1) в защищенном наследовании общественные и защищенные члены защищенных членов в класс. В частном наследстве, все частное. Однако производный класс никогда не сможет получить доступ к частные члены базового класса, это так?

Да.

Полученный класс может доступ к общественным и защищенным членов в обоих случаях. Правильно ли это?

Да.

2) Я заметил, что частные члены базового класса никогда не будет затронутый производным классом. Так почему являются ли частные члены унаследованы?

Потому что они являются частью базового класса, и вам нужен базовый класс, который является частью вашего производного класса. Обратите внимание: вы все равно можете манипулировать некоторым состоянием (если есть), поддерживаемым в базовом классе, используя функции-члены, не поддерживающие public/protected.

Ответ 5

1) Вы правы. Никакой тип наследования не позволяет доступ к частным членам (только объявления friend позволяют это)

2) Они "унаследованы" в том смысле, что объект типа Derived, когда он хранится в памяти, включает в себя все элементы данных Derived и Base, включая частных членов Base. Частные члены не могут просто уйти с тех пор, когда методы Base будут запущены на этом объекте, им нужно будет получить доступ к частным членам Base.

Кроме того, имена частных членов Base технически находятся в области в производных методах, но, конечно, вы получите ошибку компиляции, если попытаетесь получить к ним доступ.