|
Программирование >> Программирование на языке c++
виртуальные функции не могут быть статическими (их нельзя объявить со спецификатором static); виртуальные функции можно объявить со спецификатором friend для другого класса; виртуальными могут быть только компоненты-функции (глобальные функции не могут быть виртуальными); виртуальная функция может, в частности, использоваться только в базовом классе и не использоваться в производных классах. Поэтому функцию можно объявить виртуальной и тогда, когда предположительно позже можно рассмотреть ее новые версии, но на данном этапе абсолютной уверенности в этом нет; новая версия виртуальной функции в производном классе должна иметь то же число и те же типы аргументов, что и версия виртуальной функции для базового класса. В противном случае функция будет не виртуальной, а переопределенной; почти всегда виртуальные функции разных версий должны возвращать одни и те же значения. Однако из этого правила есть одно исключение. Виртуальная функция в производном классе может возвращать указатель или ссылку на некоторый объект другого производного класса П; виртуальная функция в базовом классе может возвращать указатель или ссылку на некоторый объект другого базового класса Б и Б<-П (см. последний пример); если виртуальная функция объявлена в производном классе со спецификатором virtual, то снова можно рассматривать новые версии этой функции в классах, наследуемых из этого производного класса. Если спецификатор virtual опущен, то новые версии функции далее не будут рассматриваться (однако, как и раньше, здесь можно использовать механизмы переопределения функции); для вызова виртуальной функции требуется больше времени, чем для вызова невиртуальной функции. Кроме того, в. первом случае требуется дополнительная память для хранения виртуальной таблицы (см. прил. 2.2); > если некоторая виртуальная функция вызывается с использованием ее полного имени (например, book:: displayO )> то виртуальный механизм не применяется; > деструктор может быть виртуальным, а конструктор - нет. 4.4. Абстрактные классы Существуют классы, которые выражают некоторую абстрактную концепцию. Объекты этих классов не могут быть определены. Например, можно объявить класс, называемый ГРАФИЧЕСКАЯ ФИГУРА. Однако это используется только для того, чтобы определить некоторые данные и функции, которые являются общими для разных графических фигур. Поэтому наш класс ГРАФИЧЕСКАЯ ФИГУРА имеет смысл только как база для некоторых производных классов, объявляющих конкретные фигуры (ЛИНИЯ, ПРЯМОУГОЛЬНИК и т. п.). В действительности такой класс задает некоторые имена, которые будут использоваться в конкретных производных классах. Классы языка С++, подобные рассмотренному выше классу ГРАФИЧЕСКАЯ ФИГУРА, включают так называемые pure виртуальные функции (pure virtual functions). Здесь речь идет о виртуальных функциях, которые не имеют практического применения и существуют только как некоторая идея (абстракция). Поэтому будем называть эти функции абстрактными (т. е. в действительности не существующими). Абстрактные виртуальные функции при объявлении должны приравниваться нулю, например: class shape { public: virtual void draw(void) = 0; virtual void move(int,int) = 0; virtual void copy(int,int) = 0; .....................}; Если класс имеет хотя бы одну абстрактную виртуальную функцию, он называется абстрактным. Для таких классов нельзя создать объекты. Они могут использоваться только как базовые классы для других классов: class line : public shape { int x begin,y begin,x end,y end; public: void draw(void); void move{int,int); void copy(int,int); ................. }; Если абстрактная виртуальная функция не описана в производном классе, то она остается абстрактной виртуальной функцией в производном классе, и, значит, производный класс тоже будет являться абстрактным. Основная идея абстрактных классов заключается в том, чтобы описать интерфейс, не обращая внимания на то, как он будет в действительности реализован. Так, для приведенного выше примера, можно определить интерфейс с абстрактным классом ГРАФИЧЕСКАЯ ФИГУРА. Интерфейс фактически позволяет выразить то, что можно делать с графическими фигурами и как это делать (как взаимодействовать с объектом через сообщения). Например, такими действиями могут быть: нарисовать (draw) с возможным сообщением нарисуй себя ; переместить (move); скопировать (сору); скрыть (hide); показать (show); повернуть (rotate); изменить размер (resize) и т. п. При объявлении абстрактного класса мы только хотим определить эти действия (интерфейс), не говоря о том, как мы будем их выполнять. Позже, в производных классах, соответствующие функции будут описаны. При этом взаимодействие с любым производным объектом осуществляется по единым правилам. Ниже приведен пример программы, в которой объявляются абстрактные классы. #include <iostream.h>
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |