C++ final specifier 禁止派生类和禁止重写函数
You can use the final
specifier to designate virtual functions that cannot be overridden in a derived class. You can also use it to designate classes that cannot be inherited.
可以使用 final
说明符指定无法在派生类中重写的虚函数,还可以使用它指定无法继承的类。
final
is context-sensitive and has special meaning only when it’s used after a function declaration or class name; otherwise, it’s not a reserved keyword.
final
是上下文相关的,并且仅在函数声明或类名之后使用时才具有特殊含义;否则,它不是保留关键字。
When final
is used in class declarations, base-classes
is an optional part of the declaration.
在类声明中使用 final
时,base-classes
是声明的可选部分。
final specifier:final 说明符
1. 禁止派生类
可以将类指定为 final
,确保不能将类用作基类。
禁止派生 CBox
类:
class CBox final {
// Class details ...
};
定义中类名后面的 final
修饰符告诉编译器不允许从 CBox
类中派生。final
不是关键字,只在这个上下文中有特殊的含义。不能把关键字用作名称,但可以把 final
用作变量名。
The next example uses the final
specifier to specify that a class cannot be inherited.
下一个示例使用 final
说明符指定无法继承类。
class BaseClass final {
};
// Compiler error: BaseClass is marked as non-inheritable
class DerivedClass : public BaseClass {
};
如果类用 final
修饰符定义,该类就不能用作另一个类的基类。尝试把 final
类用作基类,编译器会生成一个错误消息。
2. 禁止重写函数
禁止重写类的某个函数成员,可能是希望保护某行为的特定方面。可以把成员函数指定为 final
,该成员函数将不能重写。
final
修饰符告诉编译器成员函数不能被重写。
The following example uses the final specifier to specify that a virtual
function cannot be overridden.
下面的示例使用 final
说明符指定无法重写虚函数。
class BaseClass {
virtual void func() final;
};
class DerivedClass : public BaseClass {
// Compiler error: attempting to override a final function
virtual void func();
};
如果类的函数成员用 final
修饰符指定,派生类就不能重写该函数。否则编译器会生成一 个错误消息。
如果我们把函数定义成 final
了,则之后任何尝试覆盖该函数的操作都将引发错误:
struct D2 : B {
// 从 B 继承 f2() 和 f3(),覆盖 fl(int)
void fl(int) const final; // 不允许后续的其他类覆盖 f1(int)
};
struct D3 : D2 {
void f2(); // 正确:覆盖从间接基类 B 继承而来的 f2()
void fl(int) const; // 错误:D2 已经将 f1(int) 声明成 final
};
final
和 override
说明符出现在形参列表 (包括任何 const 或引用修饰符) 以及尾置返回类型之后。
3. 防止发生继承
C++11 新标准提供了一种防止继承发生的方法,在类名后跟一个修饰符 final
:
class NoDerived final { /* */ }; // NoDerived 不能作为基类
class Base { /* */ };
class Last final : Base { /* */ }; // Last 不能作为基类,不能继承 Last
class Bad1 : NoDerived { /* */ }; // 错误:NoDerived 是 final 的
class Bad2 : Last { /**/ }; // 错误:Last 是 final 的
Standard Template Library,STL:标准模板库
4. Compiler Error C2723
'function'
: 'specifier'
specifier illegal on function definition
error C2723: '***': 'final' specifier illegal on function definition
The specifier cannot appear with a function definition outside of a class declaration. The virtual
specifier can be specified only on a member function declaration within a class declaration.
说明符不能与类声明外部的函数定义同时出现,仅能对类声明内的成员函数声明指定 virtual
说明符。
struct X {
virtual void f();
virtual void g();
};
virtual void X::f() {} // C2723
// try the following line instead
void X::f() {}
References
[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/
[2] Ivor Horton’s Beginning Visual C++ 2013, (美) Ivor Horton 著, 李周芳, 江凌 译. Visual C++ 2013 入门经典[M]. 第 7 版. 清华大学出版社, 2015.
http://www.wrox.com/WileyCDA/WroxTitle/productCd-1118845714.html
- 9.5 禁止派生类
- 9.7.3 禁止重写函数
[3] C++ Primer, (美) Stanley B. Lippman, (美) Josée Lajoie, (美) Barbara E. Moo 著, 王刚, 杨巨峰 译. C++ Primer 中文版[M]. 第 5 版. 电子工业出版社, 2013.
https://www.informit.com/store/c-plus-plus-primer-9780321714114
[4] cppreference.com - C++ reference, https://en.cppreference.com/w/cpp/language/final
[5] C++ override specifier (C++ override 说明符), https://blog.csdn.net/chengyq116/article/details/140222797