C++中关键字 override 的简析

 更新时间:2021年09月27日 14:39:27   作者:干燥剂  
这篇小文来聊聊 C++中的关键字 override,它的含义其实两句话就说完了,但为了叙述的完整性,让我们从虚函数说起。感兴趣的小伙伴可以跟着小编一起学习下面文章内容

在C++中,虚函数是最常见的实现多态的机制之一,来个最简单的例子温习一下:

class Base // 基类
{
public:
    virtual void f(){cout << "Base::f()" << endl;}
};
​
class Derived1 : public Base // 派生类1
{
    virtual void f(){cout << "Derived1::f()" << endl;}
};
​
class Derived2 : public Base // 派生类2
{
    virtual void f(){cout << "Derived2::f()" << endl;}
};

以上是一个基类 Base 及其派生子类的最简示例,基类中有一个普通虚函数 f( ),并且派生类们都复写(即override)了该虚函数。

以上代码的含义再清楚不过:我们希望通过基类指针或者基类引用,可以调用派生类版本的函数 f( ),以此实现所谓的多态,如下代码所示:

Base *b;
    
b  = new Derived1;
b->f(); // 打印 "Derived1::f()"
    
b = new Derived2;
b->f(); // 打印 "Derived2::f()"

但,作为一名普通虚函数 f( ),它实际上并不要求我们一定要复写(即override)它,假如你在派生类中不复写它,那么派生类将很自然地使用基类所提供的备用版本。

危险就在于此,人类是一个有诸多毛病的物种,其中一个根深蒂固的毛病是自以为是和粗心大意,因此以下代码很有可能出自某个同胞之手:

class Derived3 : public Base // 派生类3
{
    // 注意:以下函数有参数
    // 人类以为复写了基类虚函数,但实际并没有
    virtual void f(int){cout << "Derived3::f()" << endl;}
};

很明显,这位同胞的本意与以上两个派生类相同:派生出Derived3,并复写虚函数 f( )。很可惜,如果此时这位同胞贸然执行如下代码,将带来灾难性的后果:

Base *b;
b = new Derived3;
b->f(); // 原想打印 "Derived2=3::f()"
        // 实际却打印"Base::f()"!

如果这不够灾难,可以将函数 f( ) 想象成民航飞机的起飞引导程序。

现在问题很明显了:

派生类的虚函数的复写,很有可能出现乌龙——人类自以为复写了基类的虚函数(比如 void f( )) ,但实际上却写了另一个函数(比如 void f(int)) ,要命的是C++语法并不制止这种愚蠢的行为,它会以为这是我们出于某种神秘的原因才这么干的。

然后,执行程序,就这。。

解决办法:

消除人类与编译器之间深刻的误会,即:我们在想复写虚函数的时候,也同时将此想法明明白白地告诉编译器,别让它有什么误会。怎么告诉它呢?蹬蹬噔噔憋了半天主角终于出场鸟:

class Derived3 : public Base // 派生类3
{
    // 注意:
    // 此处的 override 明明白白告诉编译器:我要复写虚函数
    // 但由于基类没有 void f(int),因此此处将报错!哦也!
    virtual void f(int) override 
    {cout << "Derived3::f()" << endl;}
};

到此这篇关于C++中关键字 override 的简析的文章就介绍到这了,更多相关C++中关键字 override 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++11原子操作详解

    C++11原子操作详解

    这篇文章主要为大家介绍了C++的原子操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • Qt 关于容器的遍历迭代器的使用问题小结

    Qt 关于容器的遍历迭代器的使用问题小结

    Qt是一个跨平台的 C++ 开发库,主要用来开发图形用户界面程序,当然也可以开发不带界面的命令行程序,本文重点给大家介绍Qt 关于容器的遍历迭代器的使用问题小结,感兴趣的朋友一起看看吧
    2022-03-03
  • Qt数据库应用之实现数据的导入与导出

    Qt数据库应用之实现数据的导入与导出

    QT中涉及到数据库相关的项目,几乎都需要将少量的信息数据导出到文件保存好,然后用户可以打开该表格进行编辑,编辑完成后保存,再重新导入到软件中。所以本文将具体为大家介绍一下这一功能如何实现,感兴趣的可以跟随小编一起试一试
    2022-01-01
  • OpenCV实现图像角点检测

    OpenCV实现图像角点检测

    这篇文章主要为大家详细介绍了OpenCV实现图像角点检测,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Qt sender()函数的具体使用

    Qt sender()函数的具体使用

    在处理信号时,Qt提供了一个特殊的函数sender(),可以返回发送信号的对象指针,以实现更灵活的代码逻辑,本文就来介绍一下Qt sender()函数的具体使用,感兴趣的可以了解一下
    2024-01-01
  • C++实现LeetCode(146.近最少使用页面置换缓存器)

    C++实现LeetCode(146.近最少使用页面置换缓存器)

    这篇文章主要介绍了C++实现LeetCode(146.近最少使用页面置换缓存器),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 你不知道的C++中namespace和using的用法实例

    你不知道的C++中namespace和using的用法实例

    在C++语言编写的程序中,变量和函数等的作用范围是有一定限制的,下面这篇文章主要给大家介绍了一些你不知道的C++中namespace和using的用法,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • C语言实现学生宿舍信息管理系统课程设计

    C语言实现学生宿舍信息管理系统课程设计

    这篇文章主要为大家详细介绍了C语言实现学生宿舍信息管理系统课程设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • VS编译出现MSB3073命令的解决方案

    VS编译出现MSB3073命令的解决方案

    =error MSB3073是Visual Studio编译器报出的错误,本文主要介绍了VS编译出现MSB3073命令的解决方案,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • C++面向对象之类和对象那些你不知道的细节原理详解

    C++面向对象之类和对象那些你不知道的细节原理详解

    C++是面向对象编程的,这也是C++与C语言的最大区别,下面这篇文章主要给大家介绍了关于C++面向对象之类和对象的细节原理的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05

最新评论