22 Доступ к базовым и производным классам.

При объявлении производного класса Bl, B2 ... в разделяемом запятой базовом-списке:

ключ-класса D:базовый-список {<список-компонентов>}

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

Решение здесь состоит в том, чтобы использовать в базовом-списке спецификаторы доступа.

Поскольку сам базовый класс может являться производным классом, то вопрос об атрибуте доступа решается рекурсивно: необ­ходимо отслеживать его до тех пор пока не достигнут "самый" ба­зовый класс, породивший все остальные.

При объявлении D можно задать спецификатор доступа public или private перед классами в базовом-спнске

class D: public B1, private В2, …{ ... }

Задать в базовом-сппске protected нельзя. Объединения не мо­гут содержать базовых классов и не могут сами быть использованы в качестве базовых классов. Эти модификаторы не изменяют атрибутов доступа базовых элементов с точки зрения базового класса, хотя и могут изменить атрибуты доступа базовых элементов с точки зрения производных классов. Умолчанием является private, если D — объявление класса class, и public, если D — объявление структуры struct.

Производный класс наследует атрибуты доступа базового класса следующим образом:

Базовый класс  public:

элементы public базового класса становятся элементами public производного класса. Элементы protected базового класса становятся элементами protected производного класса. Элемен­ты private базового класса остаются для базового класса private.

Базовый класс private:

И public, и protected элементы базового private класса становятся private элементами производного класса. Элементы private базового класса остаются для базового класса private.

   В обоих случаях элементы private базового класса были и оста­ются недоступными для методов производного класса, пока в описании базового класса не будут явно заданы объявления friend, гарантирующие доступ. Например:

class Х : А

{ // умолчание для класса -

// private A

}

/* класс Х является производным от класса А */

class Y : В, public С {   // переопределяет

// умолчание для С

}

/* класс Y является производным (множественное наследование) от В и С. По умолчанию - private В */

struct S : D  {   // умолчание для struct - public D

/* struct S - производная от D */

}

struct Т : private D, Е {  // переопределяет

// умолчание для D

// Е по умолчанию

// pub1iс

}

/* struct Т является производной (множественное наследование) от D и Т. По умолчанию - public E */

Действие спецификаторов доступа в базовом списке можно скорректировать при помощи уточненного-имени в объявлениях public или protected для производного класса, например:

class B

{

int a;   // по умолчанию private

public:

int d,c;

int Bfunc (void);

};

class X: private B { // теперь в X a, d, c, и Bfunc - private

int d; // по умолчанию private. ПРИМЕЧАНИЕ: а в Х недоступна

public:

B::c; // с была private; теперь она public

int d;

int Xfunc(void); //внешняя по отношению к В и Х

Функция Efunc может использовать только имена с атрибутом public, например с, е и Xfunc.

Функция Xfunc в Х является производной от private В, поэтому она имеет доступ к:

"скоррсктированной-к-типу-public" с,

"private-относительно-Х" компонентам В:b и Bfunc;

"собственным private и public" компонентам X: d, e и Xfunc.

Однако Xfunc не имеет доступа к "private - относительно - В" компоненту а.

Hosted by uCoz