Управление доступом к членам базового класса



 

Если один класс наследует другой, члены базового класса становятся членами производного. Статус доступа членов базового класса в производном классе определяется спецификатором доступа, используемым для наследования базового класса. Спецификатор доступа базового класса выражается одним из ключевых слов: public , private или protected . Если спецификатор доступа не указан, то по умолчанию используется спецификатор private , если речь идет о наследовании типа class . Если же наследуется тип struct , то при отсутствии явно заданного спецификатора доступа по умолчанию используется спецификатор public . Рассмотрим рамификацию (разветвление) использования спецификаторов public или private . (Спецификатор protected описан в следующем разделе.)

Если базовый класс наследуется как public‑класс, его public‑члены становятся public‑членами производного класса.

Если базовый класс наследуется как publie ‑класс, все его public ‑члены становятся public ‑членами производного класса. Во всех случаях private ‑члены базового класса остаются закрытыми в рамках этого класса и не доступны для членов производного. Например, в следующей программе public ‑члены класса base становятся public ‑членами класса derived . Следовательно, они будут доступны и для других частей программы.

 

 

Поскольку функции set() и show() (члены класса base) унаследованы классом derived как public ‑члены, их можно вызывать для объекта типа derived в функции main(). Поскольку члены данных i и j определены как private ‑члены, они остаются закрытыми в рамках своего класса base .

Если базовый класс наследуется как private‑класс, его public‑члены становятся private‑членами производного класса.

Противоположностью открытому (public ) наследованию является закрытое (private ). Если базовый класс наследуется как private ‑класс, все его public ‑члены становятся private ‑членами производного класса. Например, следующая программа не скомпилируется, поскольку обе функции set() и show() теперь стали private ‑членами класса derived , и поэтому их нельзя вызывать из функции main().

 

 

Важно запомнить, что в случае, если базовый класс наследуется как private ‑класс, его открытые члены становятся закрытыми (private ) членами производного класса. Это означает, что они доступны для членов производного класса, но не доступны для других частей программы.

 

Использование защищенных членов

 

Член класса может быть объявлен не только открытым (public ) или закрытым (private ), но и защищенным (protected ). Кроме того, базовый класс в целом может быть унаследован с использованием спецификатора protected . Ключевое слово protected добавлено в C++ для предоставления механизму наследования большей гибкости.

Если член класса объявлен с использованием спецификатора protected , он не будет доступен для других элементов программы, которые не являются членами данного класса. С одним важным исключением доступ к защищенному члену идентичен доступу к закрытому члену, т.е. к нему могут обращаться только другие члены того же класса. Единственное исключение из этого правила проявляется при наследовании защищенного члена. В этом случае защищенный член существенно отличается от закрытого.

Спецификатор доступа protected объявляет защищенные члены или обеспечивает наследование защищенного класса.

Как вы знаете, закрытый член базового класса не доступен никаким другим частям программы, включая и производные классы. Однако с защищенными членами все обстоит иначе. Если базовый класс наследуется как public ‑класс, защищенные члены базового класса становятся защищенными членами производного класса, т.е. доступными для производного класса. Следовательно, используя спецификатор protected , можно создать члены класса, которые закрыты в рамках своего класса, но которые может унаследовать производный класс, причем с получением доступа к ним.

Рассмотрим следующий пример программы.

 

 

Поскольку класс base унаследован классом derived открытым способом (т.е. как public‑класс), и поскольку члены i и j объявлены защищенными в классе base , функция setk() (член класса derived) может получать к ним доступ. Если бы члены i и j были объявлены в классе base закрытыми, то класс derived не мог бы обращаться к ним, и эта программа не скомпилировалась бы.

Узелок на память. Спецификатор protected позволяет создать член класса, который будет доступен в рамках данной иерархии классов, но закрыт для остальных элементов программы.

Если некоторый производный класс используется в качестве базового для другого производного класса, то любой защищенный член исходного базового класса, который наследуется (открытым способом) первым производным классом, может быть унаследован еще раз (в качестве защищенного члена) вторым производным классом. Например, в следующей (вполне корректной) программе класс derived2 имеет законный доступ к членам i и j .

 

 

Если базовый класс наследуется закрытым способом (т.е. с использованием спецификатора private ), защищенные (derived ) члены этого базового класса становятся закрытыми (private ) членами производного класса. Следовательно, если бы в предыдущем примере класс base наследовался закрытым способом, то все его члены стали бы private ‑членами класса derived1 , и в этом случае они не были бы доступны для класса derived2 . (Однако члены i и j по‑прежнему остаются доступными для класса derived1 .) Эта ситуация иллюстрируется в следующей программе, которая поэтому некорректна (и не скомпилируется). Все ошибки отмечены в комментариях.

 

 

Несмотря на то что класс base наследуется классом derived1 закрытым способом, класс derived1 , тем не менее, имеет доступ к public ‑ и protected ‑членам класса base . Однако он не может эту привилегию передать дальше, т.е. вниз по иерархии классов. Ключевое слово protected – это часть языка C++. Оно обеспечивает механизм защиты определенных элементов класса от модификации функциями, которые не являются членами этого класса, но позволяет передавать их "по наследству" .

Спецификатор protected можно также использовать в отношении структур. Но его нельзя применять к объединениям, поскольку объединение не наследуется другим классом. (Некоторые компиляторы допускают использование спецификатора protected в объявлении объединения, но, поскольку объединения не могут участвовать в наследовании, в этом контексте ключевое слово protected будет равносильным ключевому слову private .)

Спецификатор защищенного доступа может стоять в любом месте объявления класса, но, как правило, protected ‑члены объявляются после (объявляемых по умолчанию) private ‑членов и перед public ‑членами. Таким образом, самый общий формат объявления класса обычно выглядит так.

 

 

Напомню, что раздел защищенных членов необязателен.

 


Дата добавления: 2018-09-22; просмотров: 500; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!