Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOAP.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
494.59 Кб
Скачать

Пример замещения функций (практикум)

#include <iostream>

using namespace std;

class Base {

public : void Display(){cout << “Hello, world !”<<endl;}

};

class Derived: public Base {

public :

void Display(){

Base:: void Display();

cout << “How are you ?” <<endl;}

};

class SubDerived: public Derived {

public :

void Display(){

Derived:: void Display();

cout << “Bye!” <<endl;}

};

int main()

{

SubDerived sd;

sd.Display();

return 0;

}

+++++++++++++++++++++

Hello, world!

How are you?

Bye!

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

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

monstr *p;

p = new daemon;

p -> draw(1,1,1,1);

Вызов происходит в соответствии с типом указателя, а не фактическим типом объекта, на который он ссылается, поэтому будет «нарисован» monstr, а не daemon. Этот процесс - ранее связывание. Явное преобразование типа указателя

(daemon * p) -> draw(1,1,1,1)

не всегда возможно (параметр функции – указатель, список указателей …).

Позднее связывание через виртуальные методы.

virtual void draw( int x, int y, int scale, int position);

  • Если в базовом классе метод – виртуальный, то в производном классе с тем же набором параметров – виртуальный, с отличающимся набором параметров – обычный.

  • Виртуальные методы наследуются. Можно переопределять, при этом права доступа изменить нельзя.

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

  • Виртуальный метод может быть friend , но не может быть static.

  • Если есть описание виртуального метода, то он должен быть определен хотя бы как чисто виртуальный с признаком =0 вместо тела:

virtual void f(int) =0;

и он должен переопределяться в производном классе.

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

monstr *p, *r;

r = new monstr;

p = new daemon;

r -> draw(1,1,1,1);

p -> draw(1,1,1,1);

p -> monstr:: draw(1,1,1,1);

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

Виртуальный – метод, ссылка на который разрешается на этапе выполнения программы.

Для каждого класса с виртуальными методами создается таблица виртуальных методов (vtbl) с адресами памяти виртуальных методов.

Каждый объект содержит срытое дополнительное поле ссылки (vptr)- заполняется конструктором при создании объекта. При компиляции ссылки на методы – через vptr. При выполнении адрес выбирается в момент обращения к методу.

Рекомендуется делать виртуальными деструкторы (возможны динамические объекты, delete работает с size_t).

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

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

  • Нельзя использовать при явном приведении типов, для описания типа параметра функции, типа возвращаемого функцией значения.

  • Допускается объявлять ссылки и указатели на абстрактный класс, если при инициализации не требуется создавать объект.

  • Если в производном классе не определены все чисто виртуальные методы,

он – абстрактный.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]