Объявление производного класса — КиберПедия 

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

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...

Объявление производного класса

2021-12-07 30
Объявление производного класса 0.00 из 5.00 0 оценок
Заказать работу

Рассмотрим сначала формальную сторону вопроса об объявлении производного класса и его возможностях. Воспользуемся в качестве базового класса вариантом нашего класса Men:

class Men{

char* name;

int age;

public:

void Set(char* n, int a){name=n; age=a;}

};

Функция Set () позволяет присваивать членам класса требуемые значения, т. е. фактически выполняет задачи конструктора и, кроме того, позволяет по ходу программы модифицировать значения данных, образующих объект класса.


Образуем от класса Men производный класс MenEx, введя в него новое данное-член wages для хранения зарплаты. Для того чтобы сделать класс MenEx производным от Men, используется следующая конструкция:

class MenEx:public Men{// Класс Men указан как базовый для MenEx

...// Описание класса MenEx

};

Ключевое слово public перед именем базового класса объявляет все открытые и защищенные члены базового класса такими же (открытыми и защищенными) для производного класса, и, следовательно, доступны в нем. Однако закрытые члены базового класса недоступны производному. Так, в нашем случае данные name и age, хотя и будут входить в состав объектов класса MenEx, недоступны в них для прямого обращения. Доступ к закрытым данным базового класса осуществляется только через открытые функции базового класса, в нашем примере через функцию Set ().

В целом определение класса MenEx может выглядеть следующим образом:

class MenEx:public Men{

int wages;

public:

void Set(char*n,int a,int w){// Заместим функцию Men::Set()

wages=w;

Men::Set(n,a);// Вызовем исходную (замещенную) функцию Set()

};

Открытая функция Set () класса Men доступна в классе MenEx, однако с ее помощью можно придать значения только данным name и age, а нам надо еще инициализировать переменную wages. Потому функцию Set () придется заместить, т. е. описать в производном классе функцию с тем же именем, но с другим списком параметров и другим содержимым.

Функция Set () класса MenEx будет принимать три аргумента по числу данных в обоих классах. В переменную wages легко передать значение одного из аргументов (последнего в нашем примере):

wages=w;

Однако к переменным name и age обратиться напрямую нельзя. Для их инициализации придется вызывать функцию Set () базового класса:

Men::Set(n,a);

Спецификатор области видимости Men:: позволяет указать, что вызывается функция именно класса Men, а не класса MenEx.

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

Для замещения какой-либо функции базового класса нужно в производном классе объявить функцию с таким же именем. Новая функция может иметь тот же список параметров и возвращаемое значение, что и замещаемая, однако это не обязательно. Главное, чтобы у них совпадали имена. Замещение приводит к тому, что исходная функция, продолжая существовать, становится невидимой. Однако, как было показано выше, ее все же можно вызвать, если использовать оператор разрешения видимости “ :: ”.

Состав производного класса

Как уже отмечалось, производный класс наследует все содержимое базового, хотя и с некоторыми ограничениями (закрытые члены базового класса непосредственно недоступны в производном). Таким образом, производный класс шире базового. (рис. 4.1).

Как создается такой составной объект? При создании объекта производного класса сначала автоматически вызывается конструктор базового класса, конструирующий ту часть объекта, которая переходит в производный класс из базового. После этого вызывается конструктор производного класса, дополняющий объект составляющими производного класса. В нашем примитивном примере в классах нет конструкторов, однако принято считать, что в таком случае компилятор создает конструкторы по умолчанию, которые, разумеется, ничего не инициализируют, а просто выделяют память под создаваемые в программе объекты. В реальных классах конструкторы всегда присутствуют, и полезно понимать, в каком порядке они вызываются.

Рис. 4.1. Состав объекта производного класса

Точно также при отсутствии в классах явно описанных деструкторов, они создаются компилятором по умолчанию. При уничтожении объекта производного класса сначала вызывается деструктор производного класса, уничтожающий более специализированную часть объекта, затем деструктор базового класса, уничтожающий общую часть.

Защищенные члены класса

В последнем примере данные-члены обоих классов объявлены (по умолчанию) закрытыми, как это обычно и делается. Однако к закрытым данным базового класса нельзя обратиться из производного. Решить эту проблему можно двумя способами: предусмотреть в базовом классе открытые функции для доступа к данным или объявить данные базового класса защищенными (protected). Защищенные данные по-прежнему закрыты для программы, которая не может их случайно разрушить, однако из функций производного класса к ним доступ есть. Модифицируем последний пример, объявив данные базового класса защищенными и введя в производный класс функцию Print () для их распечатки:

class Men{

protected:

char* name; int age;

public:

void Set(char* n, int a){name=n; age=a;}

};

class MenEx:public Men{

int wages;

public:

void Set(char*n,int a,int w){// Заместим функцию Men::Set ()

name=n; age=a; wages=w;

}

void Print(){

char txt[50];

wsprintf(txt,”Имя: %s\nВозраст: %d\nЗарплата: %d”,

      name, age, wages);

MessageBox(NULL,txt,”MenEx”,MB_OK);

}

};

Поскольку защищенные данные базового класса непосредственно доступны в производном, отпала необходимость вызова функции Set () базового класса в замещающей функции Set () класса MenEx; в ней можно инициализировать данные обоих классов. В новой функции Print () с помощью вызова wsprintf () форми­руется символьная строка с содержимым объекта, выводимая затем в окно сообщения. Ниже приведен фрагмент программы, в которой создается, инициализируется и выводится на экран объект класса MenEx (в предположении, что оба класса описаны ранее, например, в подсоединенном к программе заголовочном файле).

MenEx* pm=new MenEx();

pm->Set("Хромов",22,5000);

pm->Print();

Вывод программы показан на рис. 4.2.

Рис. 4.2. Вывод в окно сообщения содержимого класса


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

Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.011 с.