-
指定某给虚函数不能在派生类中被覆盖
当在虚函数声明或定义中使用时,final 说明符确保函数为虚并指定其不可被派生类覆盖,否则程序为谬构(生成编译时错误)。 -
某个类不能被派生
当在类定义中使用时,final 指定此类不可在另一类的定义中的 基类说明符列表 中出现(换言之,不能派生于它),否则程序非良构(生成编译时错误)。
class Base
{
public:
virtual void foo();
};
class A : public Base
{
public:
void foo() final;
void bar() final;
};
class B final : public A
{
public:
void foo() override;
};
class C : public B
{
};
运行结果如下:
void bar() final; // 错误: bar 非虚,因此它不能是 final 的
error: virtual function ‘virtual void B::foo()’ overriding final function
25 | void foo() override; // 错误:foo 不能被覆盖,因为它在 A 中是 final 的
main.cpp:19:10: note: overridden function is ‘virtual void A::foo()’
19 | void foo() final; // Base::foo 被覆盖而 A::foo 是最终覆盖函数
main.cpp:28:7: error: cannot derive from ‘final’ base ‘B’ in derived type ‘C’
28 | class C : B // 错误:B 是 final 的
当我们声明/定义了一个虚函数时候,派生类可以选择覆盖这个虚函数,也可以选择不覆盖。
-
纯虚函数
就是一旦某个基类声明了某个纯虚函数,它的派生类在实例化的时候就必须覆盖这个函数。class Base { public: virtual void foo() = 0; }; void Base::foo () { cout << "Base:foo" << endl; } class A : public Base { public: /*void foo () { cout << "A:foo" << endl; }*/ }; int main() { A objectA; objectA.foo(); return 0; }
本例中注释掉了
A::foo()
方法,所以在就会发生编译错误。main.cpp:26:7: error: cannot declare variable ‘objectA’ to be of abstract type ‘A’ 26 | A objectA; | ^~~~~~~ main.cpp:15:7: note: because the following virtual functions are pure within ‘A’: 15 | class A : public Base | ^ main.cpp:10:6: note: ‘virtual void Base::foo()’ 10 | void Base::foo () | ^~~~
-
一般说来,有要求的覆盖的方法,就应该有禁止覆盖的手段。
class Base { public: virtual void foo() final; }; void Base::foo () { cout << "Base:foo" << endl; } class A : public Base { public: void foo () { cout << "A:foo" << endl; } }; int main() { A objectA; objectA.foo(); return 0; }
运行结果如下:
代码基本没变,只是Base::foo()声明的后面换成了final说明符。这时如果定义了A::foo()方法,就会产生如图的编译错误。17 | void foo () main.cpp:9:6: note: overridden function is ‘virtual void Base::foo()’ 9 | void Base::foo ()