![]() |
|
Программирование >> Расширенная версия языка c++
![]() Глава 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;
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |