Скачать презентацию Наследование Виртуальные методы Виртуальный метод виртуальная функция Скачать презентацию Наследование Виртуальные методы Виртуальный метод виртуальная функция

Практика.pptx

  • Количество слайдов: 21

Наследование Виртуальные методы Наследование Виртуальные методы

Виртуальный метод (виртуальная функция) — в объектно-ориентированном программировании метод (функция) класса, который может быть Виртуальный метод (виртуальная функция) — в объектно-ориентированном программировании метод (функция) класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения.

Базовый класс Свойство А Синтаксис простого наследования class A { }; class B { Базовый класс Свойство А Синтаксис простого наследования class A { }; class B { }; class C: public A { }; class D: public B Определены в базовом, но { доступны в производном }; Определено в производном классе Свойство Б Свойство В Стрелка означает наследование Производный класс Свойство А Свойство Б Свойство В Свойство Г

ПРИМЕР Рассмотрим базу данных служащих некоторой компании. Сделаем три категории служащих: менеджер, ученые и ПРИМЕР Рассмотрим базу данных служащих некоторой компании. Сделаем три категории служащих: менеджер, ученые и рабочие.

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

Они все работники одного предприятия, но у них могут быть свои особенности их работы Они все работники одного предприятия, но у них могут быть свои особенности их работы

Работник Имя Номер Менеджер Ученый Должность Сборы клуба Публикации В базе данных хранятся имена Работник Имя Номер Менеджер Ученый Должность Сборы клуба Публикации В базе данных хранятся имена служащих всех категорий и их идентификационные номера. Однако в информации о менеджерах содержится еще и Рабочий название их должности и их взносы в гольфклубы, а в информации об ученых-количество опубликованных статей.

Создаем класс работник Класс employee это наш работник. В свою очередь работника предприятия могут Создаем класс работник Класс employee это наш работник. В свою очередь работника предприятия могут быть менеджеры, ученые и обычные рабочие. Для менеджеров создаем класс class manager, в нем будет храниться информация о менеджерах, точнее его должность и его взносы в гольф клубы. Для ученых создаем класс class scientist, в нем будет храниться информация об ученых, точнее сколько раз он опубликовывал свои работы. Для обычного рабочего создаем класс class laborer. В этом классе уточняющих данных нет

Описываем класс работник employee class employee // некий сотрудник { private: char name[ LEN Описываем класс работник employee class employee // некий сотрудник { private: char name[ LEN ]; // имя сотрудника unsigned long number; // номер сотрудника public: void getname() { cout << " Vvedite familiyu: "; cin >> name; cout << " Vvedite nomer: "; cin >> number; } void putname ( ) { cout << "n Familiya: " << name; cout << "n Nomer: " << number; } virtual void getdata() {cout << " Ne virtualniy metod: "; } virtual void putdata() {cout << " Ne virtualniy metod: "; } };

В нашем классе class employee описаны два обычных и два виртуальных метода void getname() В нашем классе class employee описаны два обычных и два виртуальных метода void getname() этот метод объявляется для ввода информации о работниках, то есть их фамилии и идентификационные номера. void putname ( ) этот метод выводить на экран информацию virtual void getdata() и virtual void putdata() это два виртуальных метода. Первый метод getdata() запрашивает у пользователя должность и взносы в гольф клуб, если он запускается для обслуживания класса manager, или число публикаций для scientist. А метод putdata() выводит данные на экран.

Описываем класс manager class manager : public employee // менеджер { private: char title[ Описываем класс manager class manager : public employee // менеджер { private: char title[ LEN ]; // должность, например вице-президент double dues; // сумма взносов в гольф-клуб public: void getdata( ) { employee: : getname ( ); cout << " Vvedite dolzhnost: "; cin >> title; cout << " Vvedite summu vznosov v golf-klub: "; cin >> dues; } void putdata( ) { employee: : putname ( ); cout << "n Dolzhnost: " << title; cout << "n Summa vznosov v golf-klub: " << dues; cout << "n"; } };

В классе manager описаны функции getdata() и putdata( ). Эти функции в базовом классе В классе manager описаны функции getdata() и putdata( ). Эти функции в базовом классе описаны как виртуальные. getdata() запрашивает должность и взносы в гольф клуб. putdata( ) выводит полную информацию на экран. Также в них вызываются обычные методы базового класса employee: : getname ( ); и employee: : putname ( );

Описываем класс scientist class scientist : public employee // ученый { private: int pubs; Описываем класс scientist class scientist : public employee // ученый { private: int pubs; // количество публикаций public: void getdata ( ) { employee: : getname ( ); cout << " Vvedite kolichestvo publikaciy: "; cin >> pubs; } void putdata ( ) { employee: : putname ( ); cout << "n Kolichestvo publikaciy: " << pubs; cout << "n"; } };

В классе scientist описаны функции getdata() и putdata( ). Эти функции в базовом классе В классе scientist описаны функции getdata() и putdata( ). Эти функции в базовом классе описаны как виртуальные. getdata() запрашивает количество публикаций. putdata( ) выводит полную информацию на экран. Также в них вызываются обычные методы базового класса employee: : getname ( ); и employee: : putname ( );

Описываем класс laborer class laborer: public employee // рабочий { public: void getdata( ) Описываем класс laborer class laborer: public employee // рабочий { public: void getdata( ) { employee: : getname ( ); } void putdata( ) { employee: : putname ( ); cout << "n"; } };

В классе laborer описаны функции getdata() и putdata( ). Эти функции в базовом классе В классе laborer описаны функции getdata() и putdata( ). Эти функции в базовом классе описаны как виртуальные. В них только вызываются обычные методы базового класса employee: : getname ( ); и employee: : putname ( ); которые запрашивают информацию и выводят ее на экран.

В главной программе создаем массив указателей на базовый класс employee* emp. PTR[LEN]; emp. PTR[n] В главной программе создаем массив указателей на базовый класс employee* emp. PTR[LEN]; emp. PTR[n] = new manager; // заносим нового работника то есть //менеджера emp. PTR[n++]->getdata(); // сразу после того как мы заносим нового //работника , мы запрашиваем данные о нем, здесь происходит позднее связывание или динамическое //связывание, то есть компилятор откладывает принятие решения до запуска программы, а когда уже //известно на что указывает emp. PTR[LEN] тогда будет запущена соответствующая версия getdata(); for(j=0; jputdata(); //здесь уже полностью выводим на экран наши //данные

Главная программа int main ( ) { employee* emp. PTR[LEN]; int n=0; int j; Главная программа int main ( ) { employee* emp. PTR[LEN]; int n=0; int j; emp. PTR[n] = new manager; emp. PTR[n++]->getdata(); emp. PTR[n] = new scientist; emp. PTR[n++]->getdata(); emp. PTR[n] = new laborer; emp. PTR[n++]->getdata(); for(j=0; jputdata(); return 0; }

Результат работы Результат работы

Если же в базовом классе мы функции virtual void getdata() и virtual void putdata() Если же в базовом классе мы функции virtual void getdata() и virtual void putdata() не опишем как виртуальные то будут вызываться эти же функции только базового класса, то есть функции производного класса void getdata() и void putdata() не будут участвовать в программе. И результат будет таков:

Итак, мы увидели что можно вызывать функции с помощью одного и того же выражения, Итак, мы увидели что можно вызывать функции с помощью одного и того же выражения, то есть могут выполнятся абсолютно разные функции при одном и том же вызове! В нашем случае если указатель указывает на менеджера то запрашиваются данные менеджера. Функции выглядит одинаково это выражение getdata(); , но реально вызываются разные функции, в зависимости от значения emp. PTR[LEN].