Программирование ARM C++: спецификатор final Thu, November 21 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


C++: спецификатор final Печать
Добавил(а) microsin   

Ключевое слово final [1] указывает, что виртуальная функция [2] не может быть переопределена в производном классе, или что от этого класса не может быть наследования.

Когда ключевое слово final применяется к функции-члену класса, оно появляется сразу после декларатора функции внутри определения класса, или после определения функции внутри определения класса.

Когда ключевое слово final применяется к классу, оно появляется в начале определения класса, сразу после имени класса.

декларатор virt-spec-seq(*) pure-spec(*)                             (1)
декларатор virt-spec-seq(*) тело-функции                             (2)
class-key attr(*) class-head-name class-virt-spec(*) base-clause(*)  (3)

(1) В декларации функции-члена класса внутри определения класса final может появляться в virt-spec-seq сразу после декларатора и перед pure-spec, если это используется.
(2) В определении функции-члена класса внутри определения класса final может появляться в virt-spec-seq сразу после декларатора и перед телом функции.
(3) В определении класса final может появляться в качестве class-virt-spec сразу после имени класса, непосредственно перед двоеточием, с которого начинается base-clause, если это используется.

Примечание (*): эта часть не обязательна (опциональна).

В случаях (1,2), virt-spec-seq, если используется, будет либо override [4], либо final, либо final override, либо override final. В случае (3), допускается только значение final в качестве class-virt-spec, если это используется.

[В чем смысл final?]

Когда ключевое слово final используется в декларации или определении виртуальной функции, оно гарантирует, что функция виртуальная, и указывает, что она не может быть переопределена в производных классах. Иначе в программе ошибка (при компиляции генерируется сообщение об ошибке).

Когда ключевое слово final используется в определении класса, оно указывает, что этот класс не может появляться в списке базовых классов определения другого класса (другими словами, final-класс не может наследоваться). Иначе в программе ошибка (при компиляции генерируется сообщение об ошибке). Ключевое слово final также может использоваться в определении объединения (union), в этом случае final не оказывает никакого эффекта (кроме как влияния на результат std::is_final, см. стандарт C++14), поскольку объединения не могут наследоваться.

Слово final получает свой специальный смысл, когда используется в декларации функции-члена класса, или в заголовке класса. В других контекстах final не резервируется как ключевое слово, и может использоваться для именования объектов и функций (что конечно добавляет путаницы и так сложный синтаксис C++).

Пример:

struct Base
{
   virtual void foo();
};
 
struct A : Base
{
   void foo() final; // Base::foo переопределена и A::foo это конечный переопределитель
   void bar() final; // Ошибка: bar не может быть final, поскольку он не виртуальный
};
 
struct B final : A   // struct B обладает свойством final
{
   void foo() override; // Ошибка: foo не может быть переопределена, поскольку
                        // в A она определена как final.
};
 
struct C : B         // Ошибка: B обладает свойством final
{
};

[Ссылки]

1. final specifier (since C++11) site:cppreference.com.
2. C++: ключевое слово virtual.
3. C++: производные классы (наследование).
4. C++: спецификатор override.

 

Добавить комментарий


Защитный код
Обновить

Top of Page