Лаба по программированию. Лабораторная работа 6 Наследование классов, механизм виртуальных функций
Скачать 49.5 Kb.
|
Лабораторная работа № 6 Наследование классов, механизм виртуальных функций Цель работы – изучить одну из базовых концепций ООП – наследование классов в С++, заключающуюся в построении цепочек классов, связанных иерархически. Познакомиться с механизмом виртуальных функций. Теоретические сведения Наследование - механизм создания производного класса из базового. Т.е., к существующему классу можно что-либо добавить, или изменять его каким-либо образом для создания нового (производного) класса. Это мощный механизм для повторного использования кода. Наследование позволяет создавать иерархию связанных типов, совместно использующих код и интерфейс. Модификатор прав доступа используется для изменения доступа к наследуемым объектам в соответствии с правилами, указанными в таблице 1. Таблица 1 – Доступ в классах при наследовании
Ограничение на наследование При определении производного класса не наследуются из базового: конструкторы; деструкторы; операторы new, определенные пользователем; операторы присвоения, определенные пользователем; отношения дружественности. Использование косвенной адресации с установкой указателей на базовый класс. Механизм косвенной адресации рассмотрим на примере: class B { public: int x; B() { // Конструктор по умолчанию x = 4; } }; class D : public B { // Производный класс public: int y; D() { // Конструктор по умолчанию y = 5; } }; void main(void) { D d;// Конструктор класса D создает объект d B *p; // Указатель установлен на базовый касс p = &d;// Указатель p инициализируется адресом d // косвенное обращение к объектам базового и производного классов // «считываем их текущее состояние в переменные int i = p -> x; // Базовый класс виден напрямую int j = ( ( D* ) p )p -> y;// Прямое преобразование указателя на D // через переменные печатаем их текущее состояние cout << “ x_i= “ << i << endl; cout << “ y_j= “ << j << endl; getch(); } Виртуальная функция и механизм позднего связывания Виртуальная функция объявляется в базовом или в производном классе и, затем, переопределяется в наследуемых классах. Обычную функцию-метод можно переопределить в наследуемых классах. Однако без атрибута virtual такая функция-метод будет связана с сообщением на этапе компиляции. Атрибут virtual гарантирует позднее связывание в пределах полиморфического кластера. Часто возникает необходимость передачи сообщений объектам, принадлежащим разным классам в иерархии. В этом случае требуется реализация механизма позднего связывания. Чтобы добиться позднего связывания для объекта, его нужно объявить как указатель или ссылку на объект соответствующего класса. Для открытых производных классов указатели и ссылки на объекты этих классов совместимыми с указателями и ссылками на объекты базового класса (т.е. к объекту производного класса можно обращаться, как будто это объект базового класса). Выбранная функция-метод зависит от базового и производного класса, на объект которого указывается, но не от типа указателя. С++ поддерживает virtual функции-методы, которые объявлены в основном классе и переопределены в порожденном классе. Иерархия классов, определенная общим наследованием, создает связанный набор типов пользователя, на которые можно ссылаться с помощью указателя базового класса. При обращении к виртуальной функции через этот указатель в С++ выбирается соответствующее функциональное определение во время выполнения. Объект, на который указывается, должен содержать в себе информацию о типе, поскольку различия между ними может быть сделано динамически. Это особенность типична для ООП кода. Каждый объект “знает” как на него должны воздействовать. Эта форма полиморфизма называется чистым полиморфизмом. В С++ функции-методы класса с различным числом и типом параметров есть действительно различные функции, даже если они имеют одно и тоже имя. Виртуальные функции позволяют переопределять в управляемом классе функции, введенные в базовом классе, даже если число и тип аргументов то же самое. Для виртуальных функций нельзя переопределять тип функции. Задание к лабораторной работе Общая постановка. Программа должна содержать: базовый класс Х, включающий два элемента х1, х2 типа int, конструктор с параметрами для создания объектов в динамической области памяти, деструктор, производный класс Y, включающий один элемент у типа int , конструктор с параметрами и списком инициализаторов, передающий данные конструктору базового класса, Варианты заданий Создать как виртуальную функцию и затем определить в производном классе метод Run, вычисляющий: Сумму компонент базового и производного классов Произведение компонент базового и производного классов Сумму квадратов компонент базового и производного классов Значение х1+х2 – у Значение (х1+х2)/у Значение (х1+х2) * у Значение х1*у+х2 Значение х1+х2*у Произведение квадратов компонент базового и производного класса Значение х1*х2+у Значение х1*х2/у Значение х1*х2-у Значение (x1-x2) * y Значение (x1-x2)/y Значение х1 * х2 – у Значение (х1+х2) * 5у Значение (х1-2*х2) / у Значение х1/у+х2*y Значение х1-х2*у Значение y*х2+x1 Значение х1*х2/(2у) Значение х1*х2-3*у Значение (x1-x2) * y*x1 Значение (x1-x2)/(y*x2) Значение х1-2*(х2 – у) Значение (х1+х2)/(у*x2) Значение (х1+х2) * (у-x1) Значение х1*у+х2/y Значение х1/y+х2*у Значение х1*х2+у/(x1*x2) Значение х1*y/x2 Значение y-х1*х2 Значение (x1-x2) * y/2 Значение (x1-3*x2)/y Значение х1*х2+2*у/x1 Значение х1*х2+у*y*y |