override和final标识符

override和final标识符

overridefinal是C++引入的新的标识符。注意是标识符不是关键字。

标识符和关键字的区别

关键字(KEYWORD):也称保留字。它们为语言所用,不可用于重定义或重载。

标识符(IDENTIFIERS):一个标识符是一个由数字,下划线,小写和大写拉丁字母,和大多数 Unicode 字符组成的任意长度的序列。在声明中,可以用标识符来命名对象、引用、函数、枚举项、类型、类成员、命名空间、模板、模板特化、形参包、goto 标号,以及其他实体。

override和final标识符: 拥有特殊含义的标识符,可用作对象或函数的名字,但在某些语境拥有特殊含义。

也就是说,override和final也是标识符,也可以作为对象名,或函数名。只是在特殊的语境中有特殊的含义,和作为对象名和函数名是不冲突的。但关键字不可以这样。

例子:

#include <iostream>
class A {
public:
    virtual void show() {
        std::cout << "A::show(), override = " << override << std::endl;
    }
private:
    int override = 1;
};

class B : public A {
public:
    virtual void show() override {
        std::cout << "B::show(), override = " << override << std::endl;
    }
private:
    int override = 2;
};

int main() {
    A* ptr1 = new A();
    A* ptr2 = new B();
    ptr1->show();
    ptr2->show();
}

输出

A::show(), override = 1
B::show(), override = 2

作为函数名也是可以的,但不能同时命名override为对象名和函数名,就不举例说明了。

因为是C++11才引入的,编译时要指定C++11,否则编译有告警提示

warning: override controls (override/final) only available with -std=c++11 or -std=gnu++11 [enabled by default]

override标识符

为什么要引入override标识符? C++11以前没有时,是什么样?

还是刚才的例子:

#include <iostream>
class A {
public:
    virtual void show() {
        std::cout << "A::show(), override = " << override << std::endl;
    }
private:
    int override = 1;
};

class B : public A {
public:
    virtual void show(int a) {    //变化行
        std::cout << "B::show(), override = " << override << std::endl;
    }
private:
    int override = 2;
};

int main() {
    A* ptr1 = new A();
    A* ptr2 = new B();
    ptr1->show();
    ptr2->show();
}

输出

A::show(), override = 1
A::show(), override = 1

因为Class B的本意是重写Class A的show方法。 由于参数不一致,导致是新增了一个虚函数。由于没有重写基类方法,无法多态调用到派生类的方法。

重写函数必须有相同的类型,名称和参数列表。需要人为去保证,往往容易出现错误,导致和预期不一致。

当需要重写基类方法时,使用override关键字,这样可以将重写的检查工作交给编译器会去做。

例子中增加关键字override:

...
	virtual void show(int a) override {
...

编译将报错:

error: ‘virtual void B::show(int)’ marked override, but does not override

所有override标识符的作用是: 将重写的检查交给编译器,减少人为出错的可能。

在重写基类方法时,加上override标识符是正确的选择。

final标识符

final 是在成员函数声明或类头部中使用时有特殊含义的标识符。其他语境中它未被保留,而且可用于命名对象或函数。

final可以用于

  • 类声明: 指定某个类不能被子类继承。
  • 函数声明: 指定某个虚函数不能在子类中被覆盖。

类声明

class A final {
public:
    virtual void show() {
        std::cout << "A::show(), override = " << override << std::endl;
    }
private:
    int override = 1;
};

如果Class B继承Class A,编译将报错

error: cannot derive from ‘final’ base ‘A’ in derived type ‘B’

函数声明

    virtual void show() final {
        std::cout << "A::show(), override = " << override << std::endl;
    }

Class B重写show方法时,也会报错。

注意:

  1. final不能用于非虚方法。除非这个非虚方法是重写基类的方法。
  2. 派生类重写基类的虚方法也可以指定为final,表示这个方法不能再其被派生类重写。

参考:

https://zh.cppreference.com/w/cpp/keyword

https://www.bogotobogo.com/cplusplus/C11/C11_override_final.php

https://zh.cppreference.com/w/cpp/language/override

https://zh.cppreference.com/w/cpp/language/fin

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值