Программирование >>  Программирование на языке c++ 

1 ... 46 47 48 [ 49 ] 50 51 52 ... 159


Результаты выполнения программы имеют следующий вид:

the second guide 12

the third bool

the first guide 5

the second bool

the first bool

Следует обратить внимание на то, что одна и та же функция book::display list() используется для вывода информации о книгах, в том числе и о руководствах для программиста. Список, который она использует, содержит указатели и просто на книги и на руководства для программиста. При этом каждый раз выбирается нужная функция p->display(), которая является виртуальной.

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

#include <iostream.h> struct А{

virtual void vf1() { cout vf1\t ; }

virtual void vf2() { cout vf2\t ; }

virtual void vf3() { cout vf3\t ; }

virtual void vf4() { cout vf4\t ; } void f() { cout f\n ; } компонент-функция класса

struct в : public A {

virtual void vf1{) { cout -vf1-\t ; }

virtual void vf2() { cout -vf2-\t ; } здесь можно

использовать спецификатор virtual, но он является

избыточным, функция vf3 является не виртуальной,

а переопределенной

void vf3(char* s) { cout s \t; }

предупреждение - B::vf3 hides virtual function A::vf3

long vf4(); ошибка - conflicts with base class

void f() { cout -f-\n ; } компонент-функция класса



Struct С : public В {

void vf1() { cout -vf1-\t ; } здесь спецификатор virtual не нужен, хотя его можно и использовать

void f(A& х) первая глобальная функция

{ x.vf1{); x.vf2(); x.vf3(); x.vf4(); x.f{); }

void ff(B& x) вторая глобальная функция

{ x.vf1{); x.vf2(); x.vf3( ex1 ); x.vf4{); x.f(); }

void fff{C x) третья глобальная функция

{ x.vf1(); x.vf2(); x.vf3( ex2 ); x.vf4{); x.f(); }

void main{void)

{ A a; a - объект класса A

В b; b - объект класса В

С с; с - объект класса С

f(a); f

f(b); f

f(c); f

ff(b); -f-ff(c); -f-

fff{c); -f-

Последняя программа демонстрирует исключение из общего правила, когда виртуальные функции rf(...) в базовом и производном классах возвращают разные значения.

#include <iostream.h>

struct Base { int b; }; базовый класс (структура)

struct Derived : Base { int d; }; производный класс

(структура) struct A{ rf возвращает ссылку на базовый класс

Результат:

Результат-

-Vf1-

-vf2-

Результат:

~Vf1~

-vf2-

Результат:

-Vf1-

-vf2-

Результат:

~Vf1~

-vf2-

Результат:

~Vf1~

-vf2-



virtual Base& rf(Derived& x) { x.b=333; return x; };

struct в : public A { rf возвращает ссылку на

производный класс Derived& rf(Derived& у) { y.b=1; y.d=2; return у; };

void f(A& z,Derived& k) первая глобальная функция

{ cout (z.rf(k)).b endl; }

void ff(B& z,Derived& k) вторая глобальная функция

{ cout (z.rf(k)).b \t (z.rf(k)).d endl;

void main(void)

{ Derived d1; d 1 - объект класса Derived A A1; A1 - объект класса A

В В1; В1 - объект класса В

f{A1,d1); Результат: 333 f(B1,d1); Результат: 1 ff(B1,d1); Результат: 12

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

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

виртуальные функции позволяют строить различные версии функции для базового и производных классов;

если базовый класс Б содержит виртуальную функцию vf, и производный класс П (Б<-П) содержит функцию vf того же типа, то вызов vf для объекта класса П приводит к вызову n::vf, Даже если доступ осуществляется через указатель или ссылку на базовый класс (см. приведенные выше примеры и рис. 4.2);

> виртуальные функции можно объявить только в классах (class) и структурах (struct);



1 ... 46 47 48 [ 49 ] 50 51 52 ... 159

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика