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

1 ... 96 97 98 [ 99 ] 100 101 102 ... 227



Глава 10

Виртуальные функции

В этой главе рассматривается следующий важный аспект C++: виртуальные функции (virtualfunctions). Виртуальные функции важны потому, что они используются для поддержки динамического полиморфизма (rnn-time polymorphism). Как вы знаете, в C++ полиморфизм поддерживается двумя способами. Во-первых, при компиляции он поддерживается посредством перегрузки операторов и функций. Во-вторых, во время выполнения программы он поддерживается посредством виртуальных функций. Здесь вы узнаете, как с помощью динамического полиморфизма можно повысить гибкость программ.

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

Повторение пройденного

Перед тем как продолжить, необходимо правильно ответить на следующие вопросы и сделать упражнения.

1. Создайте манипулятор для вывода чисел в научной нотации с символом Е в верхнем регистре.

2. Напишите программу для копирования текстового файла. В процессе копирования преобразуйте каждый символ табуляции в соответствующее число пробелов.

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

4. Напишите инструкцию, которая устанавливает указатель записи на 234-й байт в файле, связанном с потоком out.

Какие функции выдают информацию о состоянии системы ввода/вывода

C++? - .-



6. Приведите хотя бы одно преимущество от использования функций ввода/вывода С++ по сравнению с соответствующими функциями системы ввода/вхвода языка С.

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

Хотя в главе 4 довольно обстоятельно обсуждались указатели C++, одна их

специфическая особенность до сих пор опускалась, поскольку она тесно

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

base *p; указатель базового класса , , . . , .

bas оЬ; объект базового класса

derived ed o]. объект производного класса

Естественно, что указатель р может указывать

на объект базового класса

р = sbase оЬ; указатель р для объекта базового класса

Кроме базового класса указатель р может указывать . . .

на объект производного класса

р = derived оЬ; указатель р для объекта производного класса

Как отмечено в комментариях, указатель базового класса может указывать

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

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

Указатель базового класса можно использовать для указания на объект производного класса, но обратный порядок недействителен. Указатель производного класса нельзя использовать для доступа к объектам базового класса. (Чтобы обойти это ограничение, можно использовать приведение типов, но

на практике так действовать не рекомендуется.)

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



Примеры

1. В этой короткой программе показано, как указатель базового класса может использоваться для доступа к объекту производного класса:

Демонстрация указателя на объект производного класса ttinclude <iostream> using namespace std;

! I

class base { -

int x; public:

voi (int i) { x = i; } int getxO ( return x; }

class derived: public base { int y; . ....... r.

public :

voi (int i) { у = i; } , . , .u int getyO {returny; } . : r;

. .J M Ч

int mamt) , . , , . ...

bas *p; указателе MBoro класса

base b ob; объект базового класса derived d ob; объект производного класса

:>

1; .1. ; : , .r [; I

,1

использование указателя р

для доступа к объекту мвого класса р =

доступ к объекту базового класса cou №т базового класса х: p->getx() \п;

использование указателя р

для доступа к объекту класса

р оЬ; указывает на объект производного класса * доступ к объекту производного класса

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

делаем это напрямую . -.,

cou Объект производного класса х: << p->getx ( ) << ;

cou Объект производного класса d ob,gety() << \п;

return 0;



1 ... 96 97 98 [ 99 ] 100 101 102 ... 227

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