Разрешает ли защищенное наследование производному классу доступ к закрытым членам его базового класса? - PullRequest
11 голосов
/ 28 января 2010

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

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

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

Ответы [ 5 ]

35 голосов
/ 28 января 2010

Вы правы по пункту № 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
}
3 голосов
/ 28 января 2010

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

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

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

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

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

1 голос
/ 28 января 2010

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

Да.

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

Да.

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

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

0 голосов
/ 28 января 2010

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

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

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

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