Ограничения виртуальных функций. Спецификатор final
Данная тема есть продолжением темы:
Содержание
- 1. Ограничения виртуальных функций
- 2. Ограничения на использование виртуальных функций. Спецификатор final
- 3. Пример использования ограничения на функцию, объявленную со спецификатором virtual
- 4. Пример применения ограничения на виртуальную функцию, объявленную со спецификатором override
- Связанные темы
Поиск на других ресурсах:
1. Ограничения виртуальных функций
На виртуальные функции накладываются следующие общие ограничения:
- виртуальные функции нужно использовать только в классах, образующих иерархию наследования;
- виртуальные функции не могут применяться как обычные функции, которые не взяты в оболочку класса;
- глобальные функции не могут быть виртуальными;
- виртуальные функции в классе не могут быть объявлены статическими с использованием ключевого слова static.
⇑
2. Ограничения на использование виртуальных функций. Спецификатор final
В языке C++ можно ограничить внедрение виртуальных функций в иерархии классов. Если необходимо запретить использование имени виртуальной функции в унаследованных классах, то для этого используется спецификатор final. Если функции в иерархии классов объявляются как невиртуальные (без спецификатора virtual), попытка использовать спецификатор final приведет к ошибке компиляции.
Объявление виртуальной функции со спецификатором final может быть рассмотрено в контексте двух приложений:
- когда функция объявляется с ключевым словом virtual. Синтаксис языка C++ позволяет объявить виртуальную функцию и, в то же время, запрещает использование имени этой функции в унаследованных классах;
- когда функция объявляется с ключевым словом override. Это случай, когда функция переопределяет одноименную функцию базового класса. Синтаксисом допускается переопределение одноименной функции базового класса без ключевого слова override.
В случае объявления функции с ключевым словом virtual в классе, общий вид такой функции следующий
virtual return_type FuncName(parameters) final { // ... }
здесь
- FuncName – имя виртуальной функции, которое запрещается использовать в унаследованных классах;
- parameters – параметры функции;
- return_type – тип возврата из функции.
Если в некотором классе виртуальная функция объявляется с модификатором override, то, чтобы запретить использование имени этой функции в унаследованных классах, используется следующая форма
return_type FuncName(parameters) override final { // ... }
или без использования ключевого слова override
return_type FuncName(parameters) final { // ... }
⇑
3. Пример использования ограничения на функцию, объявленную со спецификатором virtual
Ниже представлен пример двух классов A и B, которые образуют иерархию наследования. Класс A является базовым классом, класс B является производным (унаследованным).
В классе A объявляется виртуальная функция Print() с ключевым словом virtual. В то же время, эта функция объявляется как final. Такое объявление приведет к тому, что во всех унаследованных классах будет запрещено использовать имя Print().
// Базовый класс class A { public: // Здесь объявляется виртуальная функция со спецификатором final virtual void Print() final { cout << "A.Print()" << endl; } }; // Производный (унаследованный) класс class B :A { public: // Запрещено переопределять виртуальную функцию, // которая объявлена со спецификатором final void Print() // Здесь ошибка компиляции { cout << "B.Print()" << endl; } };
⇑
4. Пример применения ограничения на виртуальную функцию, объявленную со спецификатором override
В примере объявляется три класса с именами A, B, C, которые образуют иерархию.
Класс A размещается в вершине иерархии. В классе A объявляется виртуальная функция с ключевым словом virtual, первая в цепочке виртуальных функций.
В классе B объявляется виртуальная функция с ключевым словом override, которая продолжает цепочку виртуальных функций. Эта функция объявляется со спецификатором final. Это означает, что в унаследованном классе C запрещено использовать имя виртуальной функции.
#include <iostream> using namespace std; // Базовый класс class A { public: // Здесь объявляется виртуальная функция virtual void Print() { cout << "A::Print()" << endl; } }; // Производный (унаследованный) класс class B :A { public: // Здесь объявляется виртуальная функция, // которая ограничивает использование имени Print() в унаследованных классах void Print() override final { cout << "B::Print()" << endl; } }; // Производный класс class C :B { public: // Запрещено переопределять final-функцию B::Print() void Print() override // ошибка компиляции { cout << "C::Print()" << endl; } };
⇑
Связанные темы
- Полиморфизм. Виртуальные функции. Общие понятия. Спецификаторы virtual, override. Примеры
- Абстрактный класс. Чисто виртуальная функция. Примеры
- Наследование. Общие понятия. Использование модификаторов private, protected, public при наследовании
- Порядок вызова конструкторов при наследовании. Ограничения наследования. Свойства указателя на базовый класс
⇑