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

Использование виртуальных функций

В С++ полиморфизм поддерживается и во время компиляции и во время выполнение программы. Перегрузка функций и операций – это пример полиморфизма во время компиляции. Поддержка полиморфизма во время выполнения программы достигается использованием указателей на базовые классы и виртуальные функции.

Указатели на производные типы

Указатели на базовый тип и на производный тип зависимы. Пусть имеем базовый тип B_class и производный от B_class тип D_class. В С++ всякий указатель, объявленный как указатель на B_class, может быть также указателем на D_class.

B_class *p; // указатель на объект типа B_class

B_class B_obj; // объект типа B_class

D_class D_ob; // объект типа D_class

После этого можно использовать следующие операции:

p=&B_ob; // указатель на объект типа B_class

p=&D_ob; // указатель на объект типа D_class

Все элементы класса D_class, наследуемые от класса B_class, могут быть доступны через использование указателя p. Однако на элементы, объявленные в D_class, нельзя ссылаться, используя p. Если требуется иметь доступ к элементам, объявленным в производном классе, используя указатель на базовый класс, надо привести его к указателю на производный тип. Например, это можно сделать так:

((D_class *)p)->f();

Здесь функция f() – член класса D_class. Внешние круглые скобки необходимы. Хотя указатель на базовый класс может быть использован как указатель на производный класс, обратное, неверно: нельзя использовать указатель на производный класс для присваивания ему адреса объекта базового класса. Кроме того, указатель увеличивается или уменьшается при операциях ++ и – относительно его базового типа.

Пример использования указателей на базовый класс. При этом каждый класс будет содержать функцию void show(void), свою в каждом классе.

#include <iostream.h>

class Base {

public:

void show(void)

{ cout<<”В базовом классе Base\n”; }

};

class Derive: public Base {

public:

void show(void)

{ cout<<”В производном классе Derive\n”; }

};

class Derive1: public Base {

public:

void show(void)

{ cout<<”В производном классе Derive1\n”; }

};

class Derive2: public Base {

public:

void show(void)

{ cout<<” В производном классе Derive2\n”; }

};

void main(void)

{

Base bobj, *pb;

Derive dobj, *pd;

Derive1 d1obj, *pd1;

Derive2 d2obj, *pd2;

pb=&bobj;

bobj.show(); // вызов функции

pb->show(); // show() класса Base

pd=&dobj;

dobj.show(); // вызов функции

pd->show(); // show() класса Derive

pd1=&d1obj;

d1obj.show(); // вызов функции

pd1->show(); // show() класса Derive1

pd2=&d2obj;

d2obj.show(); // вызов функции

pd2->show(); // show() класса Derive2

pb=&dobj; // указателю на базовый класс присвоен адрес производного класса Derive

pb->show(); // вызов show() класса Base!!!!!

pb=&d1obj; // указателю на базовый класс присвоен адрес производного класса Derive1

pb->show(); // вызов show() класса Base!!!!!

((Derive1 *)pb)->show(); // Вызов функции show() класса Derive1

pd1=&d2obj; // указателю на базовый класс Derive1

// присвоен адрес производного класса Derive2

pd1->show(); // вызов функции show() класса Derive1

pd1->Base::show(); // вызов функции show() класса Base!

pd1->Derive::show(); // вызов функции show() класса Derive!

pd1->show(); // вызов функции show() класса Derive1

((Derive2 *)pb)->show(); // Вызов функции show() класса Derive2

}