русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Основы виртуальных функций


Дата добавления: 2015-07-09; просмотров: 769; Нарушение авторских прав


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

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

Класс, который содержит виртуальные функции, называется полиморфным классом. Этот термин также относится и к классу, который наследует от базового класса, содержащего виртуальную функцию.

В следующей программе продемонстрирована работа с виртуальной функцией:

 

// Короткий пример использования виртуальной функции.

#include <iostream>

#include <conio>

using namespace std;

 

 

class B {

public:

virtual void who () { // Определим виртуальную функцию

cout << "Base class\n";

}

};

class D1 : public B {

public:

void who () { // переопределим who () для Dl

cout << "First производный класс\n";



}

};

 

class D2 : public B {

public:

void who () { // переопределим wh© () для D2

cout << "Second производный класс\n";

}

};

 

int main(){

B base_obj;

B *p;

D1 D1_obj;

D2 D2_obj;

 

p = & base_obj;

p->who() ; // обращение к who из В

 

p = &D1_obj ;

p->who() ; // обращение к who из D1

 

p = &D2_obj;

p->who() ; // обращение к who из D2 1

 

getch();

return 0;

}

 

Эта программа выводит на экран следующее:

 

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

Первый производный класс

Второй производный класс

 

Рассмотрим эту программу детально, чтобы понять, как она работает.

Как вы видите, функция who()объявлена в классе В как виртуальная. Это означает, что функцию можно переопределить в производном классе. Внутри каждого из производных классов D1 и D2 функция переопределяется относительно своего класса. Внутри main() объявлены четыре переменные: base_obj, представляющая собой объект типа В; р, являющаяся указателем на объекты класса В; наконец, Dl_obj и D2_obj — объекты двух производных классов. Далее переменной р присваивается адрес объекта base_obj, после чего вызывается функция who(). Поскольку who() объявлена как виртуальная, С++ определяет во время выполнения программы, какой вариант who() вызывать, основываясь на типе объекта, на который указывает р. В данном случае р указывает на объект типа В, поэтому вызывается вариант who() из класса В. Далее по ходу программы р присваивается адрес объекта Dl_obj. Вспомним, что указатель базового класса может ссылаться на объект любого производного класса. Теперь при вызове who() С++ снова анализирует, на объект какого типа указывает р и, в зависимости от этого типа, определяет, какой вариант who() следует вызвать. Поскольку р указывает на объект типа D1, выполняется вариант who() из этого класса. Аналогично, когда р присваивается адрес D2_obj, выполняется вариант who( ), объявленный внутри D2.

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

Хотя виртуальные функции обычно вызываются посредством указателей базового класса, их можно также вызывать обычным образом, используя синтаксис с оператором-точкой. Отсюда следует, что в предыдущем примере было бы синтаксически правильно вызвать who() с помощью такого предложения:

 

D1_obj .who ( ) ;

 

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

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

 



<== предыдущая лекция | следующая лекция ==>
Указатели на производные классы | Виртуальные функции наследуются


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.452 сек.