文章目录
一.final
final指定某个虚函数不能在派生类中被覆盖,或者某个类不能被派生。
当在虚函数声明或定义中使用时,final 说明符确保函数为虚并指定它不能被派生类覆盖,否则程序非良构(生成编译时错误)。
当在类定义中使用时,final 指定此类不能在另一类的定义中的 基类说明符列表 中出现(换言之,不能派生于它),否则程序非良构(生成编译时错误)。final 也可以用于联合体定义,此时下它没有效果(除了 std::is_final 的输出结果) (C++14 起),因为不能从联合体派生。
final 是在成员函数声明或类头部中使用时有特殊含义的标识符。其他语境中它未被保留,而且可用于命名对象或函数。
C++11中增加了 fina关键字来限制某个类不能被继承,或者某个虚函数不能被重写。如果修饰函数,final只能修饰虚函数,并且要放到类或者函数的后面。下面是 final 的用法:
class A
{
public:
virtual void fun()final;
//final 限定该虚函数不能被重写
void bar()final;
//error final只能修饰虚函数
};
class B final :public A//class是最终类,不能派生出新的类,不能被继承
{
public:
virtual void fun();
//error fun不能被重写因为在A中是一个final
};
class C :public B//error B是一个最终类不能被继承
{
};
二.override
override 指定一个虚函数覆盖另一个虚函数
如果使用标识符 override,那么它紧随成员函数声明或类定义内的成员函数定义语法中的声明符之后出现。
声明符 虚说明符序列(可选) 纯说明符(可选) (1)
声明符 虚说明符序列(可选) 函数体 (2)
- 在成员函数声明中,override 可以在紧随声明符之后并在 纯说明符 之前(如有使用)的 虚说明符序列 中出现。
- 在类定义内成员函数定义中,override 可以在紧随声明符之后并紧接 函数体 之前的 虚说明符序列 中出现。
两种情况中,如果使用 虚说明符序列 ,那么它必须是 override、final、final override 或 override final 之一。
override 关键字确保在派生类中声明的重写函数与基类的虚函数有相同的签名,同时也明确表明将会重写基类的虚函数,还可以防止因疏忽把本来想重写基类的虚函数声明成重载。这样,既可以保证重写虚函数的正确性,又可以提高代码的可读性。override关键字和 final关键字一样,需要放到方法后面。
struct A
{
virtual void foo();
void bar();
};
struct B : A
{
void foo() const override; // 错误:B::foo 不覆盖 A::foo
// (签名不匹配)
void foo() override; // OK:B::foo 覆盖 A::foo
void bar() override; // 错误:A::bar 非虚
};