Получается, что в С++ должен существовать механизм, с помощью которого можно узнать тип объекта во время выполнения программы. Такой механизм в С++ есть, и он, как уже отмечалось, называется динамической идентификацией типов (RTTI). Однако в ситуациях, подобных описанным, применяется другой, более «сильный» и элегантный механизм С++ — механизм виртуальных функций (см. п. 10.3 в [1]).
Чтобы добиться разного поведения в зависимости от типа, необходимо объявить функцию-метод виртуальной; в С++ это делается с помощью ключевого слова virtual. Таким образом, в листинге 9.1 объявление метода f () в базовом и производном классах должно быть таким:
virtual int f(const int &d) // в базовом классе {return 2*d; } '
virtual int f(const int &d) // в производном классе {return d*d; }
После этого для объектов базового и производного классов мы получаем разные результаты: 11 и 26. Аналогично в листинге 9.2 объявление метода printO тоже должно начинаться со слова vi rtual:
virtual void printO const // в базовом классе { cout << "Clock!" << endl; }
virtual void printO const // в производном классе { cout << "Alarm!" << endl; }
После этого вызов sett i me О с параметром базового класса обеспечит нам вывод на экран слова «С1оск», а с параметром производного класса — слова «А1агт». И при вызове по указателю наблюдается та же картина.
Вообще-то ключевое слово vi rtual достаточно написать только один раз — в объявлении функции базового класса. Определение можно писать без слова vi rtual — все равно функция будет считаться виртуальной. Однако лучше всегда это делать явным образом, чтобы всегда по тексту было видно, что функция является виртуальной.
Для виртуальных функций обеспечивается не статическое, а динамическое (позднее, отложенное) связывание, которое реализуется во время выполнения программы. Естественно, это влечет за собой некоторые накладные расходы, однако на них можно не обращать внимания, так как обеспечивается динамический полиморфизм. Александреску в [20] указывает, что в С++ реализованы два типа полиморфизма:
• статический полиморфизм, или полиморфизм времени компиляции (compile-time polymorphism), осуществляется за счет перегрузки и шаблонов функций;
• динамический полиморфизм, или полиморфизм времени выполнения (runtime polymorphism), реализуется виртуальными функциями.
С перегрузкой функций «разбирается» компилятор, правильно подбирая вариант функции в той или иной ситуации. И полиморфизм шаблонных функций тоже реализуется на этапе компиляции. Естественно, выбор осуществляется статически. Выбор же виртуальной функции происходит динамически — при выполнении программы. Класс, включающий в себя виртуальные функции, называется полиморфным. Правила описания и использования виртуальных функций-методов следующие: 1. Виртуальная функция может быть только методом класса.
2. Любую перегружаемую операцию-метод класса можйо сделать виртуальной, например, операцию присваивания или операцию преобразования типа.
3. Виртуальная функция, как и сама виртуальность, наследуется.
4. Виртуальная функция может быть константной.
5. Если в базовом классе определена виртуальная функция, то метод производного класса с такими же именем и прототипом (включая тип возвращаемого значения и константность метода) автоматически является виртуальным (слово vi rtual указывать необязательно) и замещает функцию-метод базового класса.
6. Конструкторы не могут быть виртуальными.
7. Статические методы не могут быть виртуальными.
8. Деструкторы могут (чаще — должны) быть виртуальными — это гарантирует корректный возврат памяти через указатель базового класса.
Опубликовал Kest
November 21 2013 01:38:05 ·
0 Комментариев ·
5088 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.
В конце всего обучения с водителем-инструктором по вождению, каждый человек..Первые два этапа можно смело считать основами обучения вождению, так как они подразумевают усовершенствование навыков автомобильного вождения на учебной дороге. Это позволяет будущему водителю, как следует освоить принцип вождения, овладев такими механизмами, как старт, поворот и тормоз. Водитель должен четко осознавать последовательность всех действий, чтобы в будущем у него не возникало никаких проблем с управлением автомобиля.