C++: спецификатор final |
![]() |
Добавил(а) microsin |
Ключевое слово final [1] указывает, что виртуальная функция [2] не может быть переопределена в производном классе, или что от этого класса не может быть наследования. Когда ключевое слово final применяется к функции-члену класса, оно появляется сразу после декларатора функции внутри определения класса, или после определения функции внутри определения класса. Когда ключевое слово final применяется к классу, оно появляется в начале определения класса, сразу после имени класса. декларатор virt-spec-seq(*) pure-spec(*) (1) (1) В декларации функции-члена класса внутри определения класса final может появляться в virt-spec-seq сразу после декларатора и перед pure-spec, если это используется. Примечание (*): эта часть не обязательна (опциональна). В случаях (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. |