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

override和final标识符相关推荐

  1. @override报错_C++ 多态性:C++11:override 与 final(学习笔记:第8章 09)

    C++11:override 与 final[1] override 多态行为的基础:基类声明虚函数,继承类声明一个函数覆盖该虚函数 覆盖要求: 函数签名(signature)完全一致 函数签名包括: ...

  2. C++11新特性探究:显式override和final

    C++中,我们一般可以以基类声明纯虚函数,然后让派生类继承并重写这个虚函数,用​override表示显示覆盖基类方法,但一直没有提供一种方法来阻止派生类继承基类的虚函数. C++11标准引入了fina ...

  3. Cpp 11 / override 和 final 区别

    一.override 1.诞生原因 C++ 中,有时继承关系较复杂时,基类和派生类各自的虚函数较多,导致开发人员傻傻地分不清哪些是重写了基类的虚函数,哪些是本派生类特有的虚函数.为了解决上述问题,添加 ...

  4. C++新特性探究(二):override、final

      "改写"(override)和"重载"(overload)读起来很像,尽管这是两个毫不相干的概念. --<Effective Modern C++&g ...

  5. 关于java方法的重载(Overloading),覆写(Override)以及final 方法的几点说明

    昨天在一个群里面一个群友问道final 方法可不可以重载,我不假思索的说final 方法不能继承不能重载.后来晚上睡不着觉想想总觉得不对头,翻翻书一看自己简直就是胡说八道,才意识到这些基础概念的东西时 ...

  6. override与final

    C++11新特性: 在派生类中,重写(override)继承自基类成员函数的实现时,要满足如下条件: 基类中,成员函数声明为虚拟的(virtual) 基类和派生类中,成员函数的返回类型和异常规格必须兼 ...

  7. C++:44---关键字virtual、override、final

    一.虚函数 概念:在函数前面加virtual,就是虚函数 虚函数的一些概念: 只有成员函数才可定义为虚函数,友元/全局/static/构造函数都不可以 虚函数需要在函数名前加上关键字virtual 成 ...

  8. 看完这个你还不理解右值引用和移动构造 你就可以来咬我(下)

    共分三篇,这是第3篇.另外两篇,看完这个你还不理解右值引用和移动构造 你就可以来咬我(上),看完这个你还不理解右值引用和移动构造 你就可以来咬我(中). 下面是新标准下的其他特性(共十点),了解一下, ...

  9. 关于C++的建议,仅仅为了规范代码(二)

    参考的Andrey Karpov的<<C++编程的 42 条建议>> 这里可能有一些老古董的东西,仅供参考 11.单是文件终止符(EOF)的检查还不够. 12.自动计算字符串长 ...

最新文章

  1. 【codeforces 678E】Another Sith Tournament
  2. 明早1点去青岛,可能要两天不能写博客了
  3. ETL AUTOMATION介绍
  4. 【C++学习笔记二】C++继承
  5. 美团点评移动端基础日志库——Logan
  6. R统计绘图 - 热图美化
  7. Exception: SQLSTATE[22001]
  8. nodejs 安装express
  9. Kafka监控:Kafka-Manager
  10. 解决mysql分页数据错乱问题
  11. Android:学习路线总结,绝对干货
  12. mybatis批量删除提示类型错误
  13. POJ2115 C Looooops 扩展欧几里德
  14. 三年无bug,提升代码质量的秘诀
  15. 大衣哥家的小伟和亚楠还能走多久?
  16. 法国电子与计算机信息工程学校排名,法国工程学院的十大排名情况
  17. 如何在Windows下统计代码行数
  18. 批处理bat实现常用软件一键开启
  19. 紧随时代的步伐--Java8之Lambda表达式的使用
  20. 基于51单片机步进电机控速正反转proteus仿真

热门文章

  1. 高德地图圆圈内展示market
  2. linux perf生成火焰图,火焰图:全局视野的Linux性能剖析
  3. 仿美团饿了么选菜界面实现
  4. layui树组件(扩展为带有图标的layui树组件)
  5. STL(标准模板库)--容器(一)
  6. mac idea 创建 springboot 项目
  7. ML拍照购物功能集成教程分享
  8. 软件工程第二次作业:基于Unity的3D魔方实现
  9. 小程序深度研究报告:三大维度价值涌现,精准营销、唤起转化、连接线下
  10. catia里画铰链_汽车门铰链三维造型