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

class derived: public base {

  int j;

 public:

  // Класс derived использует оба параметра x и у а также передает их классу base.

  derived(int х, int у): base(х, у){

   j = х*у;

   cout << "Создание derived-объекта.\n";

  }

// . . .

};

При передаче аргументов конструкторам базового класса следует иметь в виду, что передаваемый аргумент может содержать любое (действительное на момент передачи) выражение, включающее вызовы функций и переменные. Это возможно благодаря тому, что C++ позволяет выполнять динамическую инициализацию данных.

Предоставление доступа

Когда базовый класс наследуется закрытым способом (как private-класс), все его члены (открытые, защищенные и закрытые) становятся private-членами производного класса. Но при определенных обстоятельствах один или несколько унаследованных членов необходимо вернуть к их исходной спецификации доступа. Например, несмотря на то, что базовый класс наследуется как private-класс, определенным его public-членам нужно предоставить public-статус в производном классе. Это можно сделать двумя способами. Во-первых, в производном классе можно использовать объявление using (этот способ рекомендован стандартом C++ для использования в новом коде). Но мы отложили рассмотрение директивы using до темы пространств имен. (Основное назначение директивы using— обеспечить поддержку пространств имен.) Во-вторых, можно настроить доступ к унаследованному члену с помощью объявлений доступа. Объявления доступа все еще поддерживаются стандартом C++, но в последнее время активизировались возражения против их применения, а это значит, что их не следует использовать в новом коде. Поскольку они все еще используются в С++-коде, мы уделим внимание этой теме.

Объявление доступа имеет такой формат:

имя_базового_класса::член;

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

Объявление доступа помещается в производном классе под соответствующим спецификатором доступа. Обратите внимание на то, что объявления типа в этом случае указывать не требуется.

Чтобы понять, как работает объявление доступа, рассмотрим сначала этот короткий фрагмент кода.

class base {

 public:

  int j; // public-доступ в классе base

};

// Класс base наследуется как private-класс.

class derived: private base {

 public:

  // Вот использование объявления доступа:

  base::j; // Теперь член j снова стал открытым.

// . . .

};

Поскольку класс base наследуется классом derived закрытым способом, его public-переменная j становится private-переменной класса derived. Однако включение этого объявления доступа

base::j;

в классе derived под спецификатором public восстанавливает public-статус члена j.

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

Использование объявления доступа иллюстрируется в следующей программе.

#include

using namespace std;

class base {

  int i; // private-член в классе base

 public:

  int j, k;

  void seti (int x) { i = x; }

  int geti() { return i; }

};

// Класс base наследуется как private-класс.

class derived: private base {

 public:

  /* Следующие три инструкции переопределяют private-наследование класса base и восстанавливают public-статус доступа для членов j, seti() и geti(). */

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги