ВУЗ:
Составители:
Рубрика:
112
void main (){
base b;
base *pb = &b;
D f;
f.i = 1 + (b.i = 1);
pb->print ();
pb = &f; // Неявное преобразование D* к Base*.
pb->print ();
}
Результат:
1 внутри base
2 внутри D
Здесь в каждом случае выполняется различная версия функции
print(). Выбор динамически зависит от типа объекта, на который ука-
зывает указатель. Служебное слово virtual означает, что функция
print() может иметь свои версии для различных порожденных классов.
Указатель на базовый класс может указывать или на объект базового
класса, или на объект порожденного класса. Выбранная функция-член
зависит от класса, на объект которого указывается, но не от типа указа-
теля. При отсутствии члена производного типа по умолчанию использу-
ется виртуальная функция базового класса. Отметим различие между
выбором соответствующей переопределенной виртуальной функции и
выбором перегруженной функции-члена (не виртуальной): перегружен-
ная функция-член выбирается во время компиляции алгоритмом, осно-
ванным на правиле сигнатур. При перегрузке функции-члены могут
иметь разные типы возвращаемого значения. Если же функция объявле-
на как virtual, то все её переопределения в порожденных классах долж-
ны иметь одну и ту же сигнатуру и один и тот же тип возвращаемого
значения. При этом в производных классах слово virtual можно и не
указывать.
В производном классе нельзя определять функцию с тем же име-
нем и с той же сигнатурой, но с другим типом возвращаемого значения,
чем у виртуальной функции базового класса. Отметим, что конструктор
не может быть виртуальным, а деструктор – может.
Рассмотрим пример.
Вычисление площадей различных фигур.
Различные фигуры будем порождать от базового класса figure.
Страницы
- « первая
- ‹ предыдущая
- …
- 108
- 109
- 110
- 111
- 112
- …
- следующая ›
- последняя »
